How to add SELECT statements in addBatch()? - java

Hi I am trying to execute couple of queries in a batch by using statement.addBatch(sql) Now I have found that if query is SELECT BLAH BLAH then it throws Exception saying BatchUpdateExecption So how do I add SELECT statement inside batch. For e.g. the following does not work because on batch contains SELECT statement
st.addBatch("UPDATE")
st.addBatch("CREATE")
st.addBatch("SELECT")
st.executeBatch()
One work around is I execute SELECT statement in st.execute("SELECT") instead of st.addBatch("SELECT"). Are there any recommended ways or best practice for this usecase? Please guide thanks in advance.

Batch statements are basically for INSERT, UPDATE and DELETE statements, they're not intended for a SELECT statement nor a DDL statement. If you want to execute a SELECT statement, do it in another Statement or PreparedStatement that won't execute the batch statements.

Even the javadoc says : typically addBatch is a SQL INSERT or UPDATE statement. It is not designed to be used for SELECT statements.Refer addBatch(String sql)
Moreover addBatch(java.lang.String) method cannot be called on a PreparedStatement or CallableStatement but addBatch() supports PreparedStatement.

If you want to execute them in one connection, one of the options is to add logic like this:
if (query.startsWith("SELECT")) {
// process SELECT query
} else {
// process UPDATE/INSERT/DELETE queries
}
but in this case, all of your SELECT queries will be executed at first queue

Related

Java mysql AWS execute succeed and then select does not return the new value

I am working with AWS RDS (specifically mysql) and I am using SQL Workbench/J as a GUI tool. My server side code written in Java and here is my code:
Insert code:
try {
Statement myStatement = insertConnectionObject.createStatement();
myStatement.executeUpdate("INSERT INTO friends VALUES('buddy', '15', '123');");
myStatement.close();
} catch(Exception ex) {
// code for handling exceptions
} finally {
myStatement.close();
insertConnectionObject.close();
}
After that, I call the select code from the same table:
try {
Statement myStatement = selectConnectionObject.createStatement();
ResultSet returnedFriends = myStatement.executeQuery("SELECT * FROM friends;");
//unfortunately, the returnedFriends will not return the new inserted value 'buddy'
} catch(Exception ex) {
// code for handling exceptions
} finally {
myStatement.close();
insertConnectionObject.
unfortunately, the returnedFriends will not return the new inserted value 'buddy'.
If I will click the 'commit any pending database changes' button in the SQL Workbench/J GUI tool, and then run the select statement, the new value 'buddy' will return.
What have I tried until now?
Use the same connection object for both insert and select.
Open and close the connection after the insert command, and after every select command.
disable the auto commit and try to commit manually.
Inserting via code, and then selecting directly from the DB.
Have you tried setAutoCommit(true) on the connection, just in case it isn't?
Also, if your select is just to get a new key don't forget you can call myStatement.getGeneratedKeys() in with the update.
You should use executeQuery() to select . executeUpdate() returns nothing but int. It should give a compile time error, are you sure that the code is compiling rather than running last working version?
executeUpdate(String sql) Executes the given SQL statement, which may
be an INSERT, UPDATE, or DELETE statement or an SQL statement that
returns nothing, such as an SQL DDL statement.
So change your select code as below:
ResultSet returnedFriends = myStatement.executeQuery("SELECT * FROM friends;");
My problem was as simple and annoying as can be - apparently, I had to close the Workbench GUI when working from the code, which is kind of wired and requires probably deeper investigation from the Workbench / AWS teams.
Anyways, after closing this interface, everything just worked.
Thanks for the help!

How to get ResultSet from executeBatch?

I need to get the result set from an executed batch :
String [] queries = {"create volatile table testTable as (select * from orders) with data;",
"select top 10 * from testTable;" ,
"drop table testTable" };
for (String query : queries) {
statement.addBatch(query);
}
statement.executeBatch();
Ones i execute batch how can i get the result set from the select query ?
In short, you should not. Plain multiple execute() should be used.
As as according to the javadoc of executeBatch(), it should not support getResultSet()/getMoreResults() API.
Also, in JDBC™ 4.0 Specification #14.1.2
Only DDL and DML commands that return a simple update count may be
executed as part of a batch. The method executeBatch throws a
BatchUpdateException if any of the commands in the batch fail to
execute properly or if a command attempts to return a result set.
But some JDBC drivers might do support, try at your own risk.
I can think of 2 options from the top of my head.
1) As the other guy said...
"Plain multiple execute() should be used"
this way you can get the result set.
2) you can query after you execute your batch and get its info from the db.
According to the Java 7 API, the 'executeBatch" function doesn't return an object of ResultSet, but an array of integers. You can process the values based on the API to see which commands in the batch were successful.

java.sql.SQLException: The method 'rollback' can't be called when a global transaction is active

I want to use java invoke a oracle store procedure to return OracleResultSet, the store procedure have execute delete, insert and select operate(involves two tables). I set auto commit false and when execute commit() occur the error like the Title.
The code like below:
conn.setAutoCommit(false);
resultSet = getResultByInvokeSP(conn);
conn.commit();
after commit use
conn.setAutoCommit(true);
Remove your calls to setAutoCommit() and commit(). The error suggests you have another framework which is handling your transactions for you.

MySQL batch stmt with Statement.RETURN_GENERATED_KEYS

I am trying to execute 2 sql statements in a batch. the first statement is an insert that uses a auto generated value for its ID. the second statement is an insert to another table but it needs to use the auto generated value from above as part of the insert value
something like (where id is just to show the auto generated field its not defined in sql
stmt.addbatch(insert into table1("id_auto_generated", "foo"));
stmt.addbatch(insert into table2("table1_id", "boo"));
the way I do it now is by using this in my second sql
insert into table2(LAST_INSERT_ID(), "boo");
Problem is its slow even in batch statements its very slow as my batch can be 50,000 inserts.
I wanted to switch to prepared statements but do not know how to use Statement.RETURN_GENERATED_KEYS or LAST_INSERT_ID() with prepared statements.
I'm not sure this is a way you can do this with addBatch except in the manner that you are using. Another thing to try is to abandon the addBatch() method and try turning off auto-commit instead. Then you can use the stmt.getGeneratedKeys();. Something like:
connection.setAutoCommit(false);
stmt.executeUpdate("insert into table1(\"id_auto_generated\", \"foo\") ...");
DatabaseResults results = stmt.getGeneratedKeys();
// extract the id from the results
stmt.executeUpdate("insert into table2(\"table1_id\", \"boo\") ...");
... many more stmts here
connection.commit();
connection.setAutoCommit(true);
Hope this helps.

SQLite Exception: Insert statement does not return a Statement

I'm using SQLiteJDBC as the wrapper for an embedded database for my small Java app. Everytime I execute an INSERT statement, I get the following exception:
query does not return ResultSet
I am wondering if the JDBC Statement.executeStatement(String) method is looking for me to return a ResultSet, but that the SQLite driver knows that INSERT statements don't return anything; maybe SQLiteJDBC is throwing an error because it shouldn't be returning the ResultSet that Statement is asking for?!?
Here is the code that is producing the exception - I have made sure to setup and close all resources properly:
statement = con.createStatement();
String sql = "INSERT INTO widgets (widget_age) VALUES (27)";
statement.executeStatement(sql);
Any ideas?!?
When you are making a change and not asking for a result back, you need to call executeUpdate() instead of executeStatement().
EDIT
I can't even find a reference to executeStatement() anywhere. Were you using executeQuery()?
Sqlite always returns a message quen you execute a Query.
It's normal to have that warning/error, it's simply that no rows where returned so you can't use them in the callback if you defined one.
PD: I also think you meant executeQuery

Categories

Resources