MySQL command SELECT values in column - JDBC - java

I'm using MySQL commands via JDBC (Java) to make changes to my database. I have implemented the following method to return the values of a column. The goal is to have the location in the column (row) correspond with their location in the array (index). This works with String columns, but with numerical columns, the ResultSet seems to place them in ascending order, thus making their positioning in the returned String array not reflect their positioning in the column. 'rs' is a ResultSet reference variable.
public String[] getColumnContents(String tableName, String columnName) {
String sql = "SELECT " + columnName + " FROM " + tableName;
String[] results = new String[SQLManager.getColumnLength(tableName, columnName)];
try {
rs = statement.executeQuery(sql);
for (int counter = 0; rs.next(); counter++) {
results[counter] = rs.getString(columnName);
}
} catch (SQLException e) {
e.printStackTrace();
}
return results;
}

It's as simple as adding an ORDER BY clause to the SQL command. Here's my working method:
public String[] getColumnContents(String tableName, String columnName) {
String sql = "SELECT " + columnName + " FROM " + tableName + " ORDER BY " + columnName1 + " ASC, " + columnName2 + " ASC";
String[] results = new String[SQLManager.getColumnLength(tableName, columnName)];
try {
rs = statement.executeQuery(sql);
for (int counter = 0; rs.next(); counter++) {
results[counter] = rs.getString(columnName);
}
} catch (SQLException e) {
e.printStackTrace();
}
return results;
}

Related

Connection.rollback() doesn't work in Java

I wrote this function to easily populate my database(mySQL) :
public boolean addItems(Connection con) throws SQLException {
try {
con.setAutoCommit(false);
String[] brands = { "Honda", "BMW", "Mercedes Benz" };
String[] optional = { "acciaio", "alluminio", "carbonio", "titanio" };
Statement statement = con.createStatement();
for (int i = 0; i < brands.length; i++) {
for (int j = 0; j < optional.length; j++) {
statement.executeUpdate("INSERT INTO chassis (idUnit, brand, material, availableItems) VALUES (1, '" + brands[i] + "', '" + optional[j] + "', 20)");
statement = Condb.replaceStatement(statement);
ResultSet rs = statement.executeQuery("SELECT * FROM chassis WHERE brand = '" + brands[i] + "' AND material = '" + optional[j] + "'");
while (rs.next()) {
statement = Condb.replaceStatement(statement);
statement.executeUpdate("INSERT INTO product_code (unitName, productCode, brand, optional) VALUES ('chassis', " + rs.getInt("productCode") + ", '" + brands[i] + "', '" + optional[j] + "')");
con.commit();
}
}
}
return true;
} catch (Exception exception) {
exception.printStackTrace();
con.rollback();
return false;
}
}
But it adds one record in 'chassis' table (first update), then it doesn't enter in the while loop ('productCode' field is an auto increment field, so I need to take it from chassis table in order to add a record in 'product_code' table).
After this, it increase the j variable, executes the update in the chassis table, enters in the while loop and at the update (in the loop) it throws a SQLException
Operation not allowed after ResultSet closed
But it never executes the rollback. So I have records in my chassis table, but product_code table is empty.
This is my replaceStatement function :
public static Statement replaceStatement(Statement stmt) {
try {
stmt.close();
Statement statement = Condb.initializeDatabase().createStatement();
return statement;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
Anyone can help me solve this issue?
You can't commit and then request a rollback. For a connection that you use with plain JDBC either make a single commit in the end or trigger a rollback if some statements fails.
So con.commit(); should be placed just before return true
Otherwise you can handle manualy multiple transactions inside your loops following this answer https://stackoverflow.com/a/47482143/7237884

How to travel the rows of sql table using index in java

I have two DB and I want to transfer data from DB A tables to DB B tables. All tables from both DB have same syntax. I have this method that takes an argument name of the table. First for loop will travel the columns and I need another for or something else that travels the rows of that specific column. That switch-case retrieve the specific datatype from table column and store it into a field and after I use that field to insert the value in the same place in the DB B. Please some suggestion? I let my trash code below:
public void getAndInsertData(String nameOfTable) {
try {
Class.forName("com.mysql.jdbc.Driver");
Connection con1 = DriverManager.getConnection(urlDB1, user1, password1);
Statement s1 = con1.createStatement();
Connection con2 = DriverManager.getConnection(urlDB2, user2, password2);
Statement s2 = con2.createStatement();
ResultSet rs1 = s1.executeQuery("SELECT * FROM " + nameOfTable);
ResultSetMetaData rsmd1 = rs1.getMetaData();
int columnCount = rsmd1.getColumnCount();
for (int column = 1; column <= columnCount; column++) {
String columnName = rsmd1.getColumnName(column);
int columnType = rsmd1.getColumnType(column);
// for (int row = 1; row <= nrRows; row++) {
switch (columnType) {
case 4:
int integerValue = rs1.getInt(row);
String integerQuery = "insert into " + nameOfTable + " (" + columnName + ") VALUES(" + integerValue
+ ");";
s2.executeUpdate(integerQuery);
s2.close();
break;
case 12:
String varcharValue = rs1.getString(row);
String varcharQuery = "insert into " + nameOfTable + " (" + columnName + ") VALUES(" + varcharValue
+ ");";
s2.executeUpdate(varcharQuery);
s2.close();
default:
System.out.println("Default");
break;
}
}
// }
} catch (Exception e) {
e.printStackTrace();
} finally {
System.out.println("Transfer done...");
}
}

Getting java.lang.reflect.InvocationTargetException while fetching the row count from each table in the database

I am working on a Java-Jdbc program which will take the row count of all the tables present in the database. To do that, I came up with the following code:
// Get the source(gp) count
public Map<String,Long> getGpTableCount() throws SQLException {
Map<String, String> gpTableMap = getScopeTableList(); // Key: Sourceschema.tablename, value: Destschema.tablename:sourcesystem1,sourcesystem2...sourcesystemn
Set<String> gpTableSet = gpTableMap.keySet(); // Gets the Source Table names - Schema.Tablename
gpCountMap = new HashMap<String, Long>();
Iterator<String> keySetIterator_gpTables = gpTableSet.iterator();
Connection gpAnalyticsCon = (Connection) DbManager.getGpConnection();
while(keySetIterator_gpTables.hasNext()) {
//getting source system names
String gpTabSchemakey = keySetIterator_gpTables.next();
String tablesnSSNs = gpTableMap.get(gpTabSchemakey);
String[] ssnArray = tablesnSSNs.split(":");
String sourceSystems = ssnArray[1];
System.out.println(sourceSystems);
if(sourceSystems.equals("No_SSNs_available") || sourceSystems == "No_SSNs_available") {
System.out.println("In the if condition");
gptableCountWithoutSsn = tblCountWithoutSsn(gpTabSchemakey, gpAnalyticsCon);
gpTabMapWoSsn.put(gpTabSchemakey, gptableCountWithoutSsn);
} else {
System.out.println("In the else condition");
//get the source system names
String inSourceSystems = "('" + sourceSystems.replace(",", "','") + "')";
String gpSchemaTableName = gpTabSchemakey;
String[] gpparts = gpSchemaTableName.split("\\."); // schema, tablename
String gpTable = gpparts[1];
String gpCountQuery = "select '" + gpTable + "' as TableName, count(*) as Count, source_system_name from " + gpSchemaTableName + " where source_system_name in " + inSourceSystems +" group by source_system_name order by source_system_name";
// resultSet(1): TableName, resultSet(2): count, resultSet(3): source_system_name
try {
PreparedStatement gp_pstmnt = gpAnalyticsCon.prepareStatement(gpCountQuery);
ResultSet gpCountRs = gp_pstmnt.executeQuery();
while(gpCountRs.next()) {
System.out.println("Tablename: " + gpCountRs.getString(1) + " Source System Name: " + gpCountRs.getString(3) + ", Count: " + gpCountRs.getLong(2));
System.out.println(" ");
ssn = getSsn(gpCountRs.getString(3));
gpCountMap.put(gpTable + ": " + gpCountRs.getString(3), gpCountRs.getLong(2));
}
} catch(org.postgresql.util.PSQLException e) {
System.out.println("Table: " + gpTable + " not found for the source system: " + ssn);
} catch(SQLException e) {
e.printStackTrace();
} catch(Exception e) {
e.printStackTrace();
}
}
}
gpAnalyticsCon.close();
return gpCountMap;
}
There are two kinds of tables in the code.
Tables that have source systems
Tables without any source systems
There is an if-else condition where tables without sourcesystem names go to 'if' and those have source systems, go to 'else' condition.
In the 'if', I am calling another method: tblCountWithoutSsn which is written as:
// Method that returns the row count of tables without any source system name
private Long tblCountWithoutSsn(String tableWithoutSsn, Connection con) throws SQLException {
String[] woSsn = tableWithoutSsn.split("\\.");
long count=0;
String tablename = woSsn[1];
String query = "select '" + tablename + "' as TableName, count(*) as count from " + tableWithoutSsn;
System.out.println("Executing table: " + tablename + " which doesn't have any source system name");
System.out.println("Query for tables with no source_systems: " + query);
PreparedStatement gpwoSsn_pstmnt = con.prepareStatement(query);
ResultSet rs = gpwoSsn_pstmnt.executeQuery();
while(rs.next()) {
count = rs.getLong(2);
}
System.out.println("TableName: " + tablename + ", count: " + count);
return count;
}
There are 41 tables without any source systems. When I execute the jar file, I could see the count such of tables:
In the if condition
Executing table: table1withoutSSN which doesn't have any source system name
Query for tables with no source_systems: select 'table1withoutSSN' as TableName, count(*) as count from analytics_view.table1withoutSSN
TableName: table1withoutSSN, count: 1764
In the if condition
Executing table: table2withoutSSN which doesn't have any source system name
Query for tables with no source_systems: select 'table2withoutSSN' as TableName, count(*) as count from ge_hr3.table2withoutSSN
TableName: table2withoutSSN, count: 473376
But as soon as it reaches the table: table3WithoutSSN the code give exception and connection closes. The exception can be seen below:
In the if condition
Executing table: table3WithoutSSN which doesn't have any source system name
Query for tables with no source_systems: select 'table3WithoutSSN' as TableName, count(*) as count from custSchema.table3WithoutSSN
Exception in thread "main" java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader.main(JarRsrcLoader.java:58)
Caused by: org.postgresql.util.PSQLException: This connection has been closed.
at org.postgresql.jdbc.PgConnection.checkClosed(PgConnection.java:803)
at org.postgresql.jdbc.PgConnection.prepareStatement(PgConnection.java:1621)
at org.postgresql.jdbc.PgConnection.prepareStatement(PgConnection.java:415)
at com.recordcount.dao.GpHiveRecords.tblCountWithoutSsn(GpHiveRecords.java:156)
at com.recordcount.dao.GpHiveRecords.getGpTableCount(GpHiveRecords.java:72)
at com.recordcount.entry.StartCount.main(StartCount.java:12)
... 5 more
The line 156 in the exception is:
PreparedStatement gpwoSsn_pstmnt = con.prepareStatement(query); from the method: `tblCountWithoutSsn`
Connection method in DBManager Class:
private static Connection gpAnalyticsConnection = null; // Creating gp connection
public static Connection getGpConnection() {
try {
Class.forName("org.postgresql.Driver");
if(gpAnalyticsConnection == null) {
gpAnalyticsConnection = DriverManager.getConnection("hostname", "username", "password");
return gpAnalyticsConnection;
} else {
return gpAnalyticsConnection;
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
return null;
} catch (SQLException e) {
e.printStackTrace();
return null;
}
}
Could anyone let me know what is the mistake I am doing here and how can I rectify that.

Can't get SQL query result, when using * (not column names)

I can only get results from a SQL query execution when I use select columnname from tablename, but not when I use select * from tablename
public static void connectAndExecute(String host, String uName, String uPass, String sqlQuery) {
try {
DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());
} catch (SQLException e) {
e.printStackTrace();
}
try {
Connection con=DriverManager.getConnection(host, uName, uPass);
String[] conData = null;
Statement stmt = null;
try {
stmt = con.createStatement();
ResultSet rs = stmt.executeQuery(sqlQuery);
/*this is the place of my problem*/
}
catch (SQLException e) {
e.printStackTrace();
}
}
catch (SQLException err) {
System.out.println(err.getMessage());
}
}
Use ResultSet.class methods to get the desired result. You can give the column names or column index.
getInt(int columnIndex)
Retrieves the value of the designated column in the current row of
this ResultSet object as an int in the Java programming language.
getString(int columnIndex)
Retrieves the value of the designated column in the current row of
this ResultSet object as a String in the Java programming language.
Here is how you can implement it:
while(rs.next()){
//Retrieve by column index
int id = rs.getInt(1); //assume id is at 1st index
int age = rs.getInt(4); //assume age is at 4th index
String first = rs.getString(2); // assume first name is at 2nd index
String last = rs.getString(3); // assume last name is at 3rd index
//Display values
System.out.print("ID: " + id); System.out.print(", Age: " + age); System.out.print(", First: " + first); System.out.println(", Last: " + last);
System.out.println(" End of one row");
}

How to update null cells of specific column with mode of that column ? (Sql using Java)

I used the following code to calculate mode of a column:
public void CalcCatValMean(String colName , String tableName){
Statement st = null;
String sql = null;
String mode = null;
try{
setConnection();
st = connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_UPDATABLE);
sql = "SELECT " + colName + " , Count(colName) AS Frequency FROM " + tableName + " GROUP BY " + colName + " HAVING Count(colName) >= ALL (SELECT Count(colName) FROM " + tableName + " GROUP BY " + colName + " )";
System.out.println("sql :" + sql);
ResultSet rset = st.executeQuery(sql);
CachedRowSet rowset = new CachedRowSetImpl();
rowset.populate(rset);
int i = 1;
while(rowset.next()) { // check if a result was returned
mode = rowset.getString(i); // get your result
System.out.println("mode is : " + mode);
i++;
}
//Clean-up environment
st.close();
closeConnection();
}
catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
But the weird thing is that its' also calculating "null" as a value & giving output of following column as "null".
null
abc
null
null
xyz
What I want to do is to calculate mode of all values of that column except null and then update null cells of that column with calculated mode.

Categories