ALGUIEN HA PROGRAMADO EL INSERT CON BATCH

CON BATCH SUBIR UN EXCEL DEMASIADO GRANDES LOS SUBE MUY RAPIDO, PERO TENGO UN PROBLEMA NO ENCUENTRO UNA FORMA DE TOMAR LA LINEA QUE ME GENRA EL ERROR :( asi que me toca usar el simple executeupdate para lograrlo.

Comentarios

Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.

public boolean

el siguiente codigo....

public boolean

public boolean insertAll(ArrayList<EmpresaDTO> Empresa) throws DAOException
    {
        boolean ok=false;
        int [] updateCounts;
        String sql=  " INSERT INTO Empresa2 (Empresa, Codempresa, Fechaingreso)"
                   + " VALUES(?,?,?)";
        final Integer batchSize = 1000;
        Integer count = 0;
        Connection db = null;
        PreparedStatement ps = null;
     
       
       
        try
        {    
              db =  Conexion.getConnectionDBCAP();
              db.setAutoCommit(false);
              ps =  db.prepareStatement(sql);
       
              for (EmpresaDTO emp: Empresa)
              {
                   ps.clearParameters();
                   ps.setString(1,emp.getCse_empresa());
                   ps.setInt(2,emp.getEmpresa().getCodEmpresa());
                   ps.setDate(3,emp.getFechaingreso());
                 
                   ps.addBatch();
     
                   if(++count % batchSize == 0)
                   {
                        ps.executeBatch();
                   }
                 
          }
             // ps.executeBatch();
              db.commit();
             
             
           
        }
       

Y haz intentado asignar una

Y haz intentado asignar una variable a la llamada de executeBatch

Según la documentación:

executeBatch() te regresa un arreglo de enteros donde cada elemento es el numero de registros que se ingresaron el la sentencia que en tu caso deber'ia de ser siempre 1, el elemento que tenga 0 es donde falla, a menos que este tirando excepción y no lo hayas mencionado en cuyo caso ese batch podría ser insertado uno a uno, pero el resto puede seguir insertando en batch.

También tienes que revisar que insertes cuando el contador no es exactamente divisible entre batchSize, por ejemplo , si tienes 1001 registros, te quedaras sin insertar el 1001, habría que revisar si count== empresas.size()

Algo así

...
List<EmpresaDTO> fallidos = new ArrayList<EmpresaDTO>();
EmpresaDTO batch = new EmpresaDTO[ batchSize ];

for ( EmpresaDTO emp: empresas ) {

     addToBatch( emp, ps ); // clear parameters, sets y addBatch() etc
     batch[count] = emp; // guardarlo temporalmente en el batch para verificarlo después

     if ( count % batchSize == 0  || count == empresas.size() ) {

         int [] r = ps.executeBatch();

        // revisar los resultados
         for ( int i = 0 ; i < r.length ; i++ ) {
               if ( r[i] != 1 ) {
                // este fallo
                fallidos.add( batch[i] );
            }            

         }

     }
     count++;
}
db.commit();
// hacer algo con los que fallaron..

OscarRyz

ok voy a verifica todo y te cuento la idea es que me evians una info todos los dias en excel, el sistema automaticamente la toma y la sube al sistema, pero las lineas que no me suban las reporto en un log y en ademas las envio a mi correo ya que es informacion critica y debe estar en el sistemas sin falla alguna.

al testear un excel con casi 10 mil registros con batch es extremadamente rapido sin el puedo tardar casi o mas del minuto subiendo el archivo pero con batch es casi de inmediato que sube la informacion, pero el problema era que no encontraba la forma que me reportara la linea que no subio, pero si me funciona seria genial por que de aqui en adelante todas mis funciones insert que programe recibirarn un arraylist ya sea de 1 o muchos objetos los cuales le aplico batch para realizar el insert :)

OscarRyz

la linea con el codigo

 addToBatch( emp, ps );

me imagino que hace lo mismo que ps.clearParameters();

lo otro es que si decido cada 100 registor hacer un ps.executebatch mi batchsize va ser de 100 y
tu tienes EmpresaDTO batch = new EmpresaDTO[ batchSize ];
si for ( EmpresaDTO emp: empresas ) {

......
} me trae 1200 empresas hay te va saltar una excepcion fuera de rango

int [] r = ps.executeBatch();

int [] r = ps.executeBatch();

en esta linea cuando se produce una exepcion se queda la aplicacion y termina la ide es lograr que si en mi excel tengo 400 filas y dos no me intertaron me diga al final la linea 2 y 80 no insertaron pero que las demas la inserte sin ningun problema.
actualmente si la linea 3 tienen problemas me inserta las dos pirimera y ahi se queda el programa.

Imagen de ezamudio

una por una

La ejecución en batch implementada en el PreparedStatement es que al primer problema se arroja una excepción y se detiene. Si quieres que se inserte todo lo posible entonces tienes que hacer tú el ciclo de inserciones y cachar la excepción para marcar ese registro que no pudiste insertar y continuar con los demás.

ezamudio

la idea es hacerlo con batch, es muy eficiente al mometo de subir grandes lotes de informacion.

Imagen de gabrie.chavarria

manejado por SQL en Oracle

se puede manejar de la siguiente manera si usas oracle y como bien lo comenta ezamudio al igual que en un prepared statement tronara si alguno de los inserts marca algun error regresandote una excepcon de sql.