query - resultset java for
¿Cómo obtener claves generadas por executeBatch sin ArrayIndexOutOfBoundsException? (1)
El siguiente método quiero INSERTAR varios registros simultáneamente.
public void insert() {
try {
this.connection.setAutoCommit(false);
PreparedStatement ps = this.connection.prepareStatement(
"INSERT INTO COMPANY (NAME,Address) Values (?,?)", new String[]{"ID"});
ps.setString(1, "X01");
ps.setString(2, "Address1");
ps.addBatch();
ps.setString(1, "Y01");
ps.setString(2, "Address2");
ps.addBatch();
//EXCEPTION OCCURS HERE
int[] numUpdates = ps.executeBatch();
for (int i = 0; i < numUpdates.length; i++) {
System.out.println("Execution " + i +
"successful: " + numUpdates[i] + " rows inserted");
}
ResultSet resultSet =
(ps).getGeneratedKeys();
while (resultSet.next()) {
String deptNoKey = resultSet.getString(1);
System.out.println("Automatically generated key value = "
+ deptNoKey);
}
} catch (BatchUpdateException b) {
// process BatchUpdateException
} catch (SQLException e) {
e.printStackTrace();
}
}
En este punto, cuando espero obtener los PK generados para cada INSERT, obtengo esta excepción
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 22 at oracle.jdbc.driver.T4CNumberAccessor.unmarshalOneRow(T4CNumberAccessor.java:250) at oracle.jdbc.driver.T4C8Oall.receive(T4C8Oall.java:754) at oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:216) at oracle.jdbc.driver.T4CPreparedStatement.executeForRows(T4CPreparedStatement.java:1250) at oracle.jdbc.driver.OraclePreparedStatement.executeForRowsWithTimeout(OraclePreparedStatement.java:14264) at oracle.jdbc.driver.OraclePreparedStatement.executeBatch(OraclePreparedStatement.java:14379) at oracle.jdbc.driver.OracleStatementWrapper.executeBatch(OracleStatementWrapper.java:589) at dbpro.SqlHelper.insert2(SqlHelper.java:988) at dbpro.SqlHelper.main(SqlHelper.java:1023) 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:483) at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)
Después de la excepción: en la tabla COMPAÑÍA, se agregaron dos registros correctamente, pero esperaba obtener un ResultSet con una fila por cada inserción realizada, para poder generar cada PK.
Esto parece ser un error en Oracle en Windows, el controlador JAR ojdbc6.jar, o (conociendo Oracle) ambos.
No hay un problema significativo con el código que ha presentado. Debería funcionar, aunque cuando lo ejecuté el número de filas insertado cada vez se devolvió como -2 (= Statement.SUCCESS_NO_INFO
), por lo que es mejor que ignore estos números.
Su código funciona bien para mí con Oracle 11g XE 11.2.0.2.0 en Linux con cuatro versiones del controlador JDBC de Oracle JAR. Sin embargo, si lo ejecuto en Windows 10 con la misma versión de Oracle XE y con ojdbc6.jar, falla con la misma ArrayIndexOutOfBoundsException que está obteniendo. El problema desaparece si utilizo ojdbc7.jar en lugar de ojdbc6.jar.
Por lo tanto, recomendaría reemplazar ojdbc6.jar con ojdbc7.jar, que puede descargar desde aquí .