Java H2 dynamically inserting data - java

Good day to you all
I am trying to import specified tables from access db to store it in a H2 embedded db to be used locally and update changes back to server (access) whenever connection is possible.
But as code below shows i am stuck at inserting dynamically data to the newly created H2 database.
I am getting this error
org.h2.jdbc.JdbcSQLException: Column "1" not found; SQL statement:
INSERT INTO Users ( ID_USER, Nt_id, Name, Level, Psw_Admin ) VALUES ( 1 ,***** ,******* ,ALL ,***** ) [42122-181]
As you see i have used preparedstatement, and used quotes (because the columns newly created are VARCHAR all) yet none of the above solved the issue
here is my code of inserting:
while (rs.next()){
String object="";
String item="";
for (int i=1;i<=columncount;i++){
object=rs.getObject(i)+"";
if (i==1){
item="`"+item+object;
}else if (i==columncount){
item=item+"` ,`"+object+"`";
} else{
item=item+"` ,`"+object;
}
System.out.println(object);
}
PreparedStatement pst3=conn2.prepareStatement("INSERT INTO Users "+" ( "+columnnamepst3+" ) VALUES ( "+item+" )");
pst3.executeUpdate();
pst3.close();
System.out.println("Done...next row");
}
rs.close();
rs is the result set from access db
conn2 is the connection to H2
EDIT1: corrected the code quoted
Thanks in advance

So in another forum someone proposed this solution and it worked so i am posting it maybe it'll help someone else
String additif="VALUES (";
for(int i1=1;i1<=columncount;i1++){
if(i1!=columncount){
additif=additif+"?,";
}else{
additif=additif+"?)";
}
}while (rs.next()){
ArrayList<String> object=new ArrayList<String>();
for (int i1=1;i1<=columncount;i1++){
object.add(""+rs.getObject(i1));
System.out.println(object);
}
PreparedStatement pst3=conn2.prepareStatement("INSERT INTO `"+Tabledb+"` "+additif);
for(int i1=0;i1<object.size();i1++){
pst3.setString(i1+1, object.get(i1));}
pst3.executeUpdate();
pst3.close();
System.out.println("Done...next row");
}
rs.close();
conn.close();
System.out.println("Done!");

Your problem seems to be the using of backticks (`) for the string values. Use apostrophes (') instead.
while (rs.next()) {
String object="";
String item="";
for (int i=1;i<=columncount;i++) {
object=rs.getObject(i)+"";
if (i==1) {
item="'"+item+object;
} else if (i==columncount) {
item=item+"' ,'"+object+"'";
} else {
item=item+"' ,'"+object;
}
System.out.println(object);
}
PreparedStatement pst3=conn2.prepareStatement("INSERT INTO Users ( "+columnnamepst3+" ) VALUES ( "+item+" )");
pst3.executeUpdate();
pst3.close();
System.out.println("Done...next row");
}
rs.close();
EDIT
As your column names seem to be prepared beforehand, you could use PrepareStatement's parameter passing abilities:
String item="";
for (int i = 1; i <= columncount; i++) {
items += (i == 1 ? "" : ", " ) + "?";
}
PreparedStatement pst3=conn2.prepareStatement("INSERT INTO Users ( "+columnnamepst3+" ) VALUES ( "+item+" )");
while (rs.next()) {
for (int i=1;i<=columncount;i++) {
pst3.setString(i,rs.getString(i));
}
pst3.executeUpdate();
System.out.println("Done...next row");
}
pst3.close();
rs.close();
Should also add some error handling (try blocks).

Related

You have an error in your SQL syntax but query runs in MySQL workbench

Query doesn't work in IntelliJ but it does in SQL workbench. On other queries the updatePreparedStatement method works. I've checked my query for syntax errors and strangely enough it does run in sql workbench. Can somebody help a noob out?
public void updatePreparedStatement(String queryWithParameters, Object ... values) {
ArrayList<Map<String, Object>> result = new ArrayList<>();
try(PreparedStatement ps = this.connection.prepareStatement(queryWithParameters)) {
for(int i=0; i<values.length; i++) {
ps.setObject(i+1, values[i]);
}
int rs = ps.executeUpdate();
}catch (SQLException e){
e.printStackTrace();
}
}
public void assignOrdersToDeliveryRoute(BigInteger routeNumber, int[] orderNumbers){
DbConnection connection = new DbConnection();
System.out.println(Arrays.toString(orderNumbers));
StringBuilder orderNumberString = new StringBuilder();
int index =1;
for (int orderNumber : orderNumbers) {
String order = String.valueOf(orderNumber);
if (index < orderNumbers.length ){
orderNumberString.append(order).append(",");
}
else {
orderNumberString.append(order);
}
index++;
}
System.out.println(orderNumberString);
String query = "SET FOREIGN_KEY_CHECKS=0; UPDATE bestelling SET bezorgroutenummer = ? WHERE bestelnummer IN (" + orderNumberString + ")";
System.out.println(query);
connection.updatePreparedStatement(query, routeNumber);
}
https://dev.mysql.com/doc/refman/8.0/en/sql-prepared-statements.html says:
SQL syntax for prepared statements does not support multi-statements (that is, multiple statements within a single string separated by ; characters).
Run your statements one at a time.

Update one column from table and insert new rows. sqlite, java

I have some problems to modify data from a table.
I need to update an entire column from a specific table and if there's no sufficient rows I need to insert more.
More exactly, the user will be able to modify data from interface, in a text area that contains current data from db.
I put all the text in a list, each line representing an element of the list.
In a certain column, I must go through each row and modify it with a list item. If there are more lines in the text area than number of rows in that table, I need to insert new ones, which will contain the remaining items from the list.
I would be grateful if someone could give me some help.
Thanks!
#FXML
public void modify() throws SQLException {
String col= selectNorme.getValue().toString();
String text=texta.getText();
List<String> l1notes= new ArrayList<>( Arrays.asList( text.split("\r\n|\r|\n") ));
Statement stmt=null;
String client = this.clientCombobox.getValue().toString();
String tab1Client= client+ "_" +this.selectLang1.getValue().toString();
String query="SELECT * FROM "+tab1Client+" WHERE ["+ selectNorme.getValue().toString()+ "]= "+col+"";
String sqlUpdate1= "UPDATE ["+tab1Client+"] SET ["+ this.selectNorme.getValue().toString() +"] = ?";
try {
Connection conn = dbConnection.getConnection();
PreparedStatement modif=conn.prepareStatement(sqlUpdate1);
int i=0;
if (rss.next()) {
stmt = conn.createStatement();
rss = stmt.executeQuery(query);
stmt.executeUpdate(sqlUpdate1);
modif.setString(1, l1notes.get(i));
i++;
modif.execute();
}
else {
PreparedStatement pstmt = conn.prepareStatement("INSERT INTO ["+this.clientCombobox.getValue().toString()+"_"+this.selectLang1.getValue().toString()+"] (["+ this.selectNorme.getValue().toString() +"]) values (?)" );
for (int row=i; row< l1notes.size(); row++)
{
pstmt.setString(1, l1notes.get(row));
pstmt.executeUpdate();
}
}
}
finally {
try {
if (conn !=null)
conn.close();
}
catch (SQLException se){
se.printStackTrace();
}
}
}

Update table SQL

I have a table that contains two columns CODE where there is all the bar code and VARIABLE initialized to 0 at the beginning . I have to update the table when I scan the bar code , I have to add 1 to variable , when I scan it twice VARIABLE =2....
I have tried to do it like but it does not work .Can anyone help?
String query = "INSERT INTO TABLE (CODE,VARIABLE) VALUES(?,?) ON DUPLICATE KEY UPDATE VARIABLE='"+VARIABLE+1+"'";
try {
if (connect != null) {
PreparedStatement statement = connect.prepareStatement(query);
statement.setString(1, "%" + res + "%");
statement.setInt(2,VARIABLE );
r=statement.executeQuery();
if (r.next()) {
message = "Updated";
String code = r.getString("CODE");
int var = r.getInt("VARIABLE");
INFOSOMME.setText(message);
INFOSOMME.setText(code);
INFOSOMME.setText(var);
} else {
message = "Error";
INFOSOMME.setText(message);
}
} else {
message = "Error in connection with SQL server";
INFOSOMME.setText(message);
}
} catch (SQLException e) {
etat = false;
message = "Got an exception!";
System.err.println(e.getMessage());
}
}
});
ERROR: 08-03 09:43:44.966 30393-30393/com.example.practicas.myapplication W/System.err: Sintaxis incorrecta cerca de la palabra clave 'ON'.
I have tried to change the query to String query="INSERT INTO TABLE(CODE,VARIABLE) VALUES(?,0);" + "Update TABLE SET VARIABLE=VARIABLE+1 WHERE CODE LIKE ?"; and I got this error /System.err: The executeQuery method must return a result set.
Try to execute the following SQL command:
String query = "INSERT INTO TABLE (CODE,VARIABLE) VALUES(?,?) ON DUPLICATE KEY UPDATE VARIABLE=(VARIABLE+1)";
I have posted a comment but better here, I guess:
executeNonQuery
Updates and Inserts don't return data, so you must not use executeQuery with them (which does return information apart from the amount of rows affected)

Java sqlite performing thousands of queries

I have a java program where I perform thousands of queries on a SQLite database inside a loop. If the query shows up empty, then I insert the row. If the query has a result, I ignore. I generally perform these individual queries in batches of 1000, but in the end there will be some hundreds of thousands of total queries to finish this task.
Because I have thousands of lines that I'm checking with individual queries, this portion of the program runs very slowly.
Is there a more efficient way to perform this many queries?
Here is the loop that constantly pulls the original data from excel docs until all the information is read:
for(int i =0;i < batchSize;i++){
try {
String[] rowReader=(dataRows.get(i));
archiveID=rowReader[16];
DIVA = rowReader[41];
//Check if already in DB. If it is not, then adds to a batch
System.out.println("checking db");
if(!isInDB(conn, archiveID, DIVA)){
stmt.setString(1,archiveID);
stmt.setString(2,DIVA);
stmt.setString(3,docName);
stmt.addBatch();
}
}catch (IndexOutOfBoundsException ex){
endOfDoc = true;
}
//dump to database every batchSize
if(++count % batchSize == 0) {
//System.out.println("executing batch");
stmt.executeBatch();
conn.commit();
count=0;
}
}
Here is the actual query method:
//returns false if combo is not in All Records, returns true if there
public static boolean isInDB(Connection conn, String archiveID, String DIVA) throws SQLException {
Connection c = conn;
Statement stmt = null;
try {
Class.forName("org.sqlite.JDBC");
stmt = c.createStatement();
ResultSet rs = stmt.executeQuery( "SELECT * FROM AllRecords WHERE ArchiveID=\"" + archiveID +"\" AND DivaCat=\""+DIVA +"\"" );
if ( rs.next() ) {
return true;
}else{
System.out.println(archiveID+DIVA+" is not in DB");
rs.close();
stmt.close();
return false;
}
} catch ( Exception e ) {
System.err.println( e.getClass().getName() + ": " + e.getMessage() );
System.exit(0);
}
return false;
}
Thanks!
Without any index, finding the desired row(s) requires that the database goes through the entire table, for each query execution.
You can optimize the lookup in this particular query by indexing both lookup columns:
CREATE INDEX whatever ON AllRecords(ArchiveID, DivaCat);
Your isInDB method connect to database each time. You dont need it. You can do that with just one query too.
sqlQuery = "SELECT * FROM AllRecords WHERE "
for(int i =0;i < batchSize;i++){
...
if(i ==0)
sqlQuery + = "ArchiveID=\"" + archiveID +"\" AND DivaCat=\""+DIVA +"\"";
else
sqlQuery + = " OR ArchiveID=\"" + archiveID +"\" AND DivaCat=\""+DIVA +"\"";
after that execute sqlQuery query and check your each row with rs results.

Comparison between two ResultSet in Java

What is the best way to handle Java ResultSet? I'm creating a Desktop application that will connect to an oracle database using JDBC.
However, I am having problem with handling ResultSets since I can't do comparison using for loop.
// create a database connection object
DB db = new DB();
// get rows of my first table and second table
ResultSet firstRS = db.getMyFirstTable();
ResultSet seconRS = db.getSecondTable();
// compare the two tables
while(firstRS.next())
{
// get the row of my first table
String firstRSRow = firstRS.getString("col1");
while(secondRS.next())
{
// get the row of my second table
String secondRSRow = seconRS.getString("col1");
// compare row from first table to the row in second table
if(firstRSRow.startsWith(secondRSRow))
{
// do some processing here....
} // end if
} // end while
} // end while
I know that this could be accomplish with Hibernate with a few lines of code but I don't have the luxury of time to study it.
I also found commons DbUtils from apache but it seems complicated for me as a novice programmer.
Is there other way/tools/libraries/framework simple enough to get ResultSet from databases and manipulate it in simple and straightforward manner?
I will also appreciate if you could direct me to a website that has sample codes concerning java database connectivity.
Thank you very much for your support.
Why ResultSet? You could easily compare values with SELECT statement. In case you still want to ResultSet then think about CachedRowSet.
DB db = new DB();
// get rows of my first table and second table
ResultSet firstRS = db.getMyFirstTable();
ResultSet seconRS = db.getSecondTable();
// compare the two tables
while(firstRS.next() || secondRS.next())
{
// get the row of my first table
String firstRSRow = firstRS.getString("col1");
String secondRSRow = seconRS.getString("col1")
// compare row from first table to the row in second table
if(firstRSRow.startsWith(secondRSRow))
{
// do some processing here....
} // end if
} // end while
public static boolean resultset(String SQL1, String SQL2){
public boolean status=false;
ResultSet ViewResultset = st.executeQuery(SQL1);
ResultSet QueryResultset = st.executeQuery(SQL2);
while (QueryResultset.next() | ViewResultset.next())
if (ViewResultset.getRow() == 0 | QueryResultset.getRow() == 0) {
break;
} else {
for (int i = 1; i < ViewResultset.getMetaData().getColumnCount() + 1; i++) {
System.out.println("OOO"+ QueryResultset.getMetaData().getColumnCount());
String columnName = ViewResultset.getMetaData().getColumnName(i);
System.out.println("ColumnName :" + columnName);
for (int j = 1; j < QueryResultset.getMetaData().getColumnCount() + 1; j++)
if (ViewResultset.getMetaData().getColumnName(i).equals(QueryResultset.getMetaData().getColumnName(j))&& !(QueryResultset.getString(columnName) == null || ViewResultset.getString(columnName) == null))
if (ViewResultset.getString(columnName).toUpperCase().contains(QueryResultset.getString(columnName).toUpperCase())) {
System.out.println(" Actual "+ ViewResultset.getMetaData().getColumnName(i) + " Expected: "+ ViewResultset.getString(columnName));
status=true;
}
else {System.out.println(" Actual "+ ViewResultset.getMetaData().getColumnName(i) + " Expected: "+ ViewResultset.getString(columnName));
}
}
}
return status;
}
}
ResultSet is a subclass of Object ultimately and we can compare two or more objects directly. A little specific to your question:
ResultSet rs=st.executeQuery(sql1);
ResultSet rs1=st.executeQuery(sql2);
where sql1 and sql2 are 2 Statements
while(rs.next() && rs1.next()){
int a=rs.next();
int b=rs1.next();
if(a==b){
System.out.println("Compairing two ResultSets");
}
}

Categories