Realización de actualizaciones por lotes en aplicaciones JDBC
En las actualizaciones de proceso por lotes, en lugar de actualizar filas de una tabla de forma individual, puede hacer que JDBC ejecute un grupo de actualizaciones al mismo tiempo. Las sentencias que se pueden incluir en un mismo lote de actualizaciones se denominan sentencias procesables por lotes.
Acerca de esta tarea
Si una sentencia tiene parámetros de entrada o expresiones de lenguaje principal, puede incluir esa sentencia solo en un lote que tenga otras instancias de la misma sentencia. Este tipo de lote se denomina lote homogéneo. Si una sentencia carece de parámetros de entrada, puede incluir esa sentencia en un lote solo si las demás sentencias del lote no tienen parámetros de entrada ni expresiones de lenguaje principal. Este tipo de lote se denomina lote heterogéneo. Dos sentencias que se puedan incluir en el mismo lote se dice que son compatibles por lote.
- addBatch
- executeBatch
- clearBatch
Utilice el siguiente método de PreparedStatement y CallableStatement para crear un lote de parámetros para que una sentencia individual se pueda ejecutar varias veces en un lote, con un conjunto de parámetros diferente para cada ejecución.
- addBatch
- Si intenta ejecutar una sentencia SELECT en un lote, se emite una excepción BatchUpdateException.
- Un objeto CallableStatement que ejecute en un lote puede contener parámetros de salida. Sin embargo, no puede recuperar los valores de los parámetros de salida. Si intenta hacerlo, se emite una excepción BatchUpdateException.
- No puede recuperar objetos ResultSet de un objeto CallableStatement que ejecute en un lote. En ese caso no se emite una excepción BatchUpdateException, pero la invocación del método getResultSet devuelve un valor nulo.
Procedimiento
Para realizar actualizaciones por lotes, siga uno de los grupos de pasos siguientes.
Ejemplo
En el siguiente fragmento de código de programa, se procesan por lotes dos conjuntos de parámetros. Luego, una sentencia UPDATE que admite dos parámetros de entrada se ejecuta dos veces, una vez con cada conjunto de parámetros. Los números que aparecen a la derecha de algunas sentencias corresponden a los pasos descritos anteriormente.
try {
…
PreparedStatement preps = conn.prepareStatement(
"UPDATE DEPT SET MGRNO=? WHERE DEPTNO=?"); 2
ps.setString(1,mgrnum1); 3a
ps.setString(2,deptnum1);
ps.addBatch(); 3b
ps.setString(1,mgrnum2);
ps.setString(2,deptnum2);
ps.addBatch();
int [] numUpdates=ps.executeBatch(); 4
for (int i=0; i < numUpdates.length; i++) { 5a
if (numUpdates[i] == SUCCESS_NO_INFO)
System.out.println("Execution " + i +
": unknown number of rows updated");
else
System.out.println("Execution " + i +
"successful: " numUpdates[i] + " rows updated");
}
conn.commit(); 5b
} catch(BatchUpdateException b) { 6
// process BatchUpdateException
}
En el código de programa siguiente, una sentencia INSERT de proceso por lotes devuelve claves generadas automáticamente.
import java.sql.*;
import com.ibm.db2.jcc.*;
…
Connection conn;
…
try {
…
PreparedStatement ps = conn.prepareStatement( 2
"INSERT INTO DEPT (DEPTNO, DEPTNAME, ADMRDEPT) " +
"VALUES (?,?,?)",
Statement.RETURN_GENERATED_KEYS);
ps.setString(1,"X01"); 3a
ps.setString(2,"Finance");
ps.setString(3,"A00");
ps.addBatch(); 3b
ps.setString(1,"Y01");
ps.setString(2,"Accounting");
ps.setString(3,"A00");
ps.addBatch();
int [] numUpdates=preps.executeBatch(); 4
for (int i=0; i < numUpdates.length; i++) { 5a
if (numUpdates[i] == SUCCESS_NO_INFO)
System.out.println("Execution " + i +
": unknown number of rows updated");
else
System.out.println("Execution " + i +
"successful: " numUpdates[i] + " rows updated");
}
conn.commit(); 5b
ResultSet[] resultList =
((DB2PreparedStatement)ps).getDBGeneratedKeys(); 5c
if (resultList.length != 0) {
for (i = 0; i < resultList.length; i++) {
while (resultList[i].next()) {
java.math.BigDecimal idColVar = rs.getBigDecimal(1);
// Get automatically generated key
// value
System.out.println("Automatically generated key value = "
+ idColVar);
}
}
}
else {
System.out.println("Error retrieving automatically generated keys");
}
} catch(BatchUpdateException b) { 6
// process BatchUpdateException
}
En el código de programa siguiente, una sentencia UPDATE de proceso por lotes devuelve claves generadas automáticamente. El código da nombre a la columna DEPTNO como una clave generada automáticamente, actualiza dos filas en la tabla DEPT de un proceso por lotes y recupera los valores de DEPTNO para las filas actualizadas. Los números que aparecen a la derecha de algunas sentencias corresponden a los pasos descritos anteriormente.
import java.sql.*;
import com.ibm.db2.jcc.*;
…
Connection conn;
…
String[] agkNames = {"DEPTNO"};
try {
…
conn.setAutoCommit(false); 1
PreparedStatement ps = conn.prepareStatement( 2
"UPDATE DEPT SET DEPTNAME=? " +
"WHERE DEPTNO=?",agkNames);
ps.setString(1,"X01"); 3a
ps.setString(2,"Planning");
ps.addBatch(); 3b
ps.setString(1,"Y01");
ps.setString(2,"Bookkeeping");
ps.addBatch();
int [] numUpdates=ps.executeBatch(); 4
for (int i=0; i < numUpdates.length; i++) { 5a
if (numUpdates[i] == SUCCESS_NO_INFO)
System.out.println("Execution " + i +
": unknown number of rows updated");
else
System.out.println("Execution " + i +
"successful: " numUpdates[i] + " rows updated");
}
conn.commit(); 5b
ResultSet[] resultList =
((DB2PreparedStatement)ps).getDBGeneratedKeys(); 5c
if (resultList.length != 0) {
for (i = 0; i < resultList.length; i++) {
while (resultList[i].next()) {
String deptNoKey = rs.getString(1);
// Get automatically generated key
// value
System.out.println("Automatically generated key value = "
+ deptNoKey);
}
}
}
else {
System.out.println("Error retrieving automatically generated keys");
}
}
catch(BatchUpdateException b) { 6
// process BatchUpdateException
}