jueves, 5 de junio de 2014

UPDATE, EN TABLA CON VARIOS MILLONES DE REGISTROS???

hola amig@ , este día se me encomendó realizar una actualización para una tabla destino que contiene 4.5 millones de registros, desde una tabla origen que contiene 8.5 millones de registros.
bueno para eso probé varias opciones desde hacer un cursor hasta hacer un merge pero los tiempos de ejecución fueron muy lentos, buscando información me encontré con un documento de ORACLE, aca les dejo el ejemplo, los conceptos a comprender son facilites; también se manejan los errores, por cuestión de tiempo no los incorporo a una tabla para manejar una estadística, ya eso seria opción de ustedes ;)

no se olviden de dejar sus comentarios....

CREATE OR REPLACE PROCEDURE SLDUSR.UPDATE_ALL_ROWS ( P_LOAÑO IN number ,
                                                                                               P_LOMES  IN number,
                                                                                               P_LODIA  IN number )
AS                                                                                  

       TYPE V_TCCCLI    IS TABLE OF NOV_L1CTLOG.TCCCLI%TYPE  INDEX BY PLS_INTEGER;
       TYPE V_TCNCON  IS TABLE OF NOV_L1CTLOG.TCNCON%TYPE  INDEX BY PLS_INTEGER;
       TYPE V_TCNFOL   IS TABLE OF NOV_L1CTLOG.TCNFOL%TYPE  INDEX BY PLS_INTEGER;
       TYPE V_LOTANT   IS TABLE OF NOV_L1CTLOG.LOTANT%TYPE INDEX BY PLS_INTEGER;
       TYPE V_LOTDES   IS TABLE OF NOV_L1CTLOG.LOTDES%TYPE INDEX BY PLS_INTEGER;
        
       TO_V_TCCCLI    V_TCCCLI;
       TO_V_TCNCON  V_TCNCON;
       TO_V_TCNFOL   V_TCNFOL;
       TO_V_LOTANT   V_LOTANT;
       TO_V_LOTDES   V_LOTDES;
   
      X_BAD_ITERATION EXCEPTION;
      PRAGMA EXCEPTION_INIT (X_BAD_ITERATION, -24381 );
    
   BEGIN
   
      SELECT  TRIM(TCCCLI)    ,
                   TRIM(TCNCON)  ,
                   TRIM(TCNFOL)   ,
                   TRIM(LOTANT)   ,
                   TRIM(LOTDES)    
      BULK COLLECT INTO  TO_V_TCCCLI   ,
                                     TO_V_TCNCON ,
                                     TO_V_TCNFOL   ,
                                     TO_V_LOTANT   ,
                                     TO_V_LOTDES    
      FROM NOV_L1CTLOG
            WHERE  LOAÑO   = P_LOAÑO AND
                           LOMES = P_LOMES AND
                          LODIA   = P_LODIA ;
   
      FORALL I IN TO_V_TCNFOL.FIRST .. TO_V_TCNFOL.LAST SAVE EXCEPTIONS
         UPDATE ASSET2
         SET TELEFONO = TO_V_LOTDES(I)
         WHERE ID_ANE_BILLING = TO_V_TCNFOL(I);

   
     DBMS_OUTPUT.PUT_LINE ( TO_CHAR(SQL%ROWCOUNT) || ' records updated.' );
     COMMIT;
   
   EXCEPTION
   
      WHEN X_BAD_ITERATION 
      THEN
         DBMS_OUTPUT.PUT_LINE ('SUCCESSFUL UPDATE OF ' || TO_CHAR(SQL%ROWCOUNT) || ' RECORDS.' );
         DBMS_OUTPUT.PUT_LINE ( 'FAILED ON ' || TO_CHAR(SQL%BULK_EXCEPTIONS.COUNT) || ' RECORDS.' );
               
         FOR I IN 1 .. SQL%BULK_EXCEPTIONS.COUNT 
         LOOP
            DBMS_OUTPUT.PUT_LINE (
                                                       'ERROR OCCURRED ON ITERATION ' ||
                                                          SQL%BULK_EXCEPTIONS(I).ERROR_INDEX ||
                                                             ' DUE TO ' ||
                                                                SQLERRM (
                                                                   -1 * SQL%BULK_EXCEPTIONS(I).ERROR_CODE)
                                                     );
                                                     
            DBMS_OUTPUT.PUT_LINE (
                                                       'NOV_L1CTLOG = ' ||
                                                          TO_CHAR (
                                                             TO_V_TCNFOL (
                                                                SQL%BULK_EXCEPTIONS(I).ERROR_INDEX )) ||
                                                       ' VALUE = ' ||
                                                          TO_CHAR (
                                                             TO_V_LOTANT (
                                                                SQL%BULK_EXCEPTIONS(I).ERROR_INDEX )) 
                                                     );  
         END LOOP;
      END UPDATE_ALL_ROWS;