I came across an old piece of code which looks like below
Statement stmt = connection.createStatement();
stmt.addBatch(insertQuery);
stmt.addBatch(insertQuery);
stmt.addBatch(insertQuery);
stmt.addBatch(insertQuery);
//there is some data which needs to be deleted before inserting the new data.
stmt.execute(deleteQuery);
stmt.executeBatch();
Here we are batching up a few query and before executing the batch this code is executing some other delete query and then executing the batch.
Is it legal to do this?
Will the above code work as expected that it will first execute the delete query and then the batch update?
The JDBC specification (version 4.3) says:
The behavior of the methods executeQuery, executeUpdate, and
execute is implementation-defined when a statement’s batch is
non-empty.
In other words, the behaviour is not specified and depends on the driver implementation, this means it should not be relied on.
A quick (but not thorough) scan of the pgjdbc sources seems to indicate that the PostgreSQL driver indeed allows you to first add statements to the batch, execute a single statement, and then execute the batch.
But in the code shown, I'd suggest to simply first execute the delete query, and only then populate and execute the batch. That order would be a lot simpler to read for people unfamiliar with the code.
Related
I am executing multiple SQL statements using single Connection and Statement object as two processes.
Pre-process (Preprocess.java)
Post-process (Postprocess.java)
My Process steps are as follows,
Creating a Connection object and setAutoCommit() as false.
Creating a Statement object.
During pre-process executing the required SQL statements using the created Statement object.
Then for post-process i pass the same Statement object and executing the required SQL statements.
Finally commit the transaction (connection.commit();) and close the Connection,Statement objects.
My Problem is:
Sometimes the post-process executed statements are not reflected in database. That is, if i insert or update any records in post-process,those records are not available in database.
But the post-process execution is working fine without any exception.
The Probability of this case is 5 out of 1/(Which means 4 times working as i expected but 1 time its problematic).
Can any one point out the problem?
I am using Jdk 1.7 and Postgresql 9.3 version.
I have to confirm that can we execute multiple select statement in one shot and get multiple resultsets. Please give me some idea for doing this.
I have to execute two select query in one statement:-
String sql="select * form test;
select * from test where empid=1;"
I am expecting to run like this :-
statement.execute(sql);
thanks
I don't believe that standard JDBC supports this. Certainly the ResultSet interface is oriented towards "multiple rows, one row at a time" - but not "multiple sets of results".
That doesn't mean it's not feasible with your specific database, however - it's possible that there's a driver for your database which extends JDBC to allow it. If you specify which database and driver you're using, we could verify that more easily.
In my opinion JDBC does not allow executing multiple statements in one go. The language used in the JDBC specification and API doc indicates that the expectation is that one Statement execution is one statement, not multiple statements (eg it uses 'a SQL statement', which when reading the SQL spec means a single SELECT, INSERT, etc). However it never explicitly states it is not allowed.
Some drivers do support execution of multiple statements in one execution, but this usually has to be explicitly enabled using a connection property. Also some databases support executing a block of stored procedure code without explicitly defining a stored procedure (in that case the block is considered to be the statement).
Create a stored procedure with those set of select statements and use Statement.getMoreResults() to check whether you have more ResultSets and use
Statement.getResultSet() to get the next ResultSet
An example is given Here
When to use statement instead of prepared statement. i suppose statement is used in queries with no parameter but why not use prepared statement ? Which one is faster for queries with no params.
I suppose statement is used in queries with no parameter but why not use prepared statement ?
That's not even close. PreparedStatements are used in the case of INSERT, UPDATE and DELETE statements that return a ResultSet or an update count. They will not work for DDL statements as pointed out by Joachim, and neither will they work for invocation of stored procedures where a CallableStatement ought to be used (this is not a difference between the two classes). As far as queries with no bind parameters are concerned, PreparedStatements can turn out to be better than Statements (see below).
Which one is faster for queries with no params.
PreparedStatements will turn out to be faster in the long run, over extended use in a single connection. This is because, although PreparedStatements have to be compiled, which would take some time (this really isn't a lot, so don't see this as a drawback), the compiled version essentially holds a reference to the SQL execution plan in the database. Once compiled, the PreparedStatement is stored in a connection specific cache, so that the compiled version may be reused to achieve performance gains. If you are using JDBC Batch operations, using PreparedStatements will make the execution of the batch much faster than the use of plain Statement objects, where the plan may have to be prepared time and again, if the database has to do so.
That's depending on Your requirement.
If you have a SQL statement which runs in a loop or frequently with different parameters then PreparedStatement is the best candidate since it is getting pre-compiled and cache the execution plan for this parameterized SQL query. Each time it runs from the same PreparedStatement object it will use cached execution plan and gives the better performance.
Also SQL injection can be avoided using PreparedStatement .
But if you are sure that you run SQL query only once, sometimes Statement will be the best candidate since when you create PreparedStatement object sometimes it make additional db call, if the driver supports precompilation, the method Connection.prepareStatement(java.lang.String) will send the statement to the database for precompilation.
Read below article to understand "Statement Versus PreparedStatement"
Java Programming with Oracle JDBC
I'm getting this BatchUpdateException from a stmt.executeBatch() statement:
BatchUpdateException: A resultset was created for update
The internet does not have any information on this exception message. What does it mean? The traceback doesn't contain anything useful other than that a stored procedure failed.
I'd interpret the message as meaning that an SQL statement that you added via addBatch() has produced a ResultSet, meaning that it's not your normal INSERT, UPDATE or DELETE statement.
Statements that should return results can't be executed in batches with JDBC.
The JDBC Tutorial (under the heading "Handling Batch Update Exceptions") confirms it:
You will get a BatchUpdateException when you call the method executeBatch if (1) one of the SQL statements you added to the batch produces a result set (usually a query) or (2) one of the SQL statements in the batch does not execute successfully for some other reason.
You seem to be running into case 1 here.
A batch-update are several insert/update/delete statements which are processed by the database together. This is usualy done for perfomance reasons. 1x 1000 inserts is much faster than 1000x 1 insert. A BatchUpdateException means 1 (or more) statements failed most often due to a constraint-violation.
You will have to look at the stored procedure to see what it has been doing. Mayby your dba can give you more information about what went wrong.
I dropped one column from the table.
When i tried to insert records to that table i was getting BatchUpdateException.
After running the below command the problem got solved
REORG TABLE TABLE_NAME
I have an application which processes a very large file and sends data to an oracle database (using Java 6, oracle 9).
In a loop, I use a PreparedStatement ps and create all SQL statements generated with ps.addBatch().
I have a situation where a BatchUpdateException bue is thrown somewhere during the ps.executeBatch(). At that point, the batch stops to be executed.
I'd like the batch execution to continue, so that I can then check on failed updates in a method processUpdateCounts(bue.getUpdateCounts()).
The javadoc about class BatchUpdateException says:
After a command in a batch update
fails to execute properly and a
BatchUpdateException is thrown, the
driver may or may not continue to
process the remaining commands in the
batch.
Is there a way to enforce continuation or do I need to alter my program so that it will execute the statement individually?
Just found this link:
JDBC Batch Update Problem
Apparently, it says there there is
NO WAY WITH ORACLE BATCH JDBC to proceed after first failure,
thus I am resorting to sending the inserts one by one.
Thank you
(sorry for not looking better to find the link above before).
there is a workaround that would allow you to use the batch feature. Instead of executing a simple INSERT statement, you can execute a PL/SQL block that will deal with the error appropriately:
BEGIN
INSERT INTO your_table VALUES (?,?,...?);
EXCEPTION
WHEN OTHERS THEN
/* deal with the error. For example, log the error id and error msg
so that you can list them after the batch */
INSERT INTO error_table VALUES (?, sqlerrm);
END
The performance should be on par with the batch insert (should be faster than individual execution of the statements). You could also call a stored procedure instead of a PL/SQL block.
Oracle itself can, see here: http://download.oracle.com/docs/cd/B19306_01/appdev.102/b14250/oci04sql.htm#sthref616
However, it doesn't seem that this functionality is exposed to JDBC, not even in the oracle specific classes.
Because of the rather useless JDBC error handling ("the driver may or may not continue"), I'm always setting a savepoint before the batch, and performing an rollback to that point on error. That's the only JDBC compliant way to establish a known state after an Oracle Batch Error--as far as I know.
Since the specification doesn't seem to mandate it (as clearly shown by the Javadoc), any "forced" continuation would have to be done on per-driver basis. A simple standard-compliant workaround would be to check the getUpdateCounts() returned array and "re-run" the batch for those statements which failed. You can make this approach a bit more sophisticated by putting in a logic for the number of retries.
Sure, this seems a bit messy (keeping track of the "batch" added and then checking the output) but would work across all databases and driver implementations. Just a thought...