FirebirdSQL / jaybird

JDBC driver for Firebird
https://firebirdsql.org/en/jdbc-driver/
GNU Lesser General Public License v2.1
93 stars 23 forks source link

PreparedStatement.executeBatch() of statement without parameters throws "Statement used in batch must have parameters [SQLState:07001, ISC error code:335545186]" (isc_batch_param) #788

Closed ErmacTheSoul closed 8 months ago

ErmacTheSoul commented 8 months ago

after updating Jaybird from version 4.0.10 to 5.0.4 we are getting errors when using method executeBatch to execute multiple SQL queries at a time:

Caused by: java.sql.SQLException: Dynamic SQL Error; SQL error code = -901; Statement used in batch must have parameters [SQLState:07001, ISC error code:335545186] at org.firebirdsql.gds.ng.FbExceptionBuilder$Type$1.createSQLException(FbExceptionBuilder.java:618)

is this a bug or maybe we need to update Firebird as well or include more parameters in our batch to execute it properly? we are using Firebird 4.0.2

can provide more logs if needed

mrotteveel commented 8 months ago

I need a minimal reproducible example, and the full exception stacktrace. However, this sounds like you're using a prepared statement batch with a statement that has no parameters.

As a workaround, set connection property userServerBatch to false.

ErmacTheSoul commented 8 months ago

log.txt

mrotteveel commented 8 months ago

Could you also provide the code (or an anonymized variant of the code) that triggers. As far as I can tell, you're doing something like:

var pstmt = connection.prepareStatement("insert into sometable default values"); // or some other statement without parameters
pstmt.addBatch();
pstmt.executeBatch();

Can you confirm that is so? I'm wondering why 1) you're using a prepared statement for a statement without parameters, and 2) using batch execution to execute a statement without parameters.

To be clear, this is something that I will fix (by falling back to emulation), if only to restore compatibility with the emulated batch feature, but especially using batch execution for something without parameters feels odd to me.

As I said previously, the workaround should be to disable the use of server batch execution with property useServerBatch set to false, but to be honest, if I'm correct about your code, then at least using normal execute() or executeUpdate() would be better, and using a normal Statement (with execute(String) or executeUpdate(String)) would make the most sense to me.