Ver Mensaje Individual
  #1 (permalink)  
Antiguo 08/05/2012, 06:33
Avatar de gnzsoloyo
gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 16 años, 5 meses
Puntos: 2658
lectura, actualización e inserción usado BULK COLLECT en PL/SQL

Buenos dias.
El titulo es mas o menos claro: necesito crear un stored proceudre en Oracle tal que realice una lectura de una tabla con más de 1000 millones de registros de 290 bytes de ancho. Obviamente estoy hablando de un enorme caudal de datos.
El proceso que debo hacer es simple:
1) Leer todos los registros de cierto rango de fechas (un año entero).
2) Crear un registro nuevo con cada uno de los leídos, con la fecha de alta actualizada.
3) Actualizar cada uno de los del año leído poniendole en un campo la fecha de baja.

He pensado hacer esto por medio de un BULK COLLECT (actualmente un SP que se usa utiliza un cursor para eso), pero como no tengo práctica en el tema, sólo teoría, tengo un par de dudas:
1) ¿El array resultante de un BULK COLLECT se puede recorrer una sola vez, o se puede hacer mas de una vez sin necesidad de volver a leer?
2) ¿Es necesario ejecutar un UPDATE con los datos del registro leído en un momento dado, o el actualiza los campos del registro del array se encarga de eso?
3) ¿Es conveniente leer toda la tabla en una sola operación, o es más performantico hacerlo en bloques de N registros, usando LIMIT?

Creo que la mejor pregunta sería: ¿Cómo sería el esquema de un SP que cumpla con lo que quiero hacer?

En principio, he bosquejado esto (lamento tener que cambiar el nombre de las talas, pero hay compromisos firmados, lo juro):
Código SQL:
Ver original
  1. PROCEDURE APPAnual
  2.  
  3.     IS
  4.     TYPE t_aplica IS TABLE OF APLICA%ROWTYPE;
  5.     DECLARE v_aplica t_aplica;
  6.     BEGIN
  7.         -- Recupero todos los registros del año anterior
  8.         SELECT  
  9.             AP.id, AP.numero, AP.cont, AP.n_serial, AP.c_serv, AP.u_alta, AP.f_alta, AP.u_baja,AP.f_baja
  10.         BULK COLLECT INTO v_aplica
  11.         FROM APLICA AP
  12.         WHERE
  13.             TO_CHAR(AP.F_ALTA,'YYYY') = TO_CHAR(SYSDATE,'YYYY')-1
  14.             AND AP.U_BAJA IS NULL
  15.             AND AP.F_BAJA IS NULL;
  16.            
  17.         -- INSERT    
  18.         FORALL i IN v_aplica.FIRST .. v_aplica.LAST
  19.         INSERT INTO APLICA(
  20.             AP.id, AP.numero, AP.cont, AP.n_serial, AP.c_serv, AP.u_alta, AP.f_alta, AP.u_baja,AP.f_baja)
  21.         VALUES(
  22.             app_seq.NEXTVAL, v_aplica(i).numero, v_aplica(i).cnt, v_aplica(i).n_serial,
  23.             v_aplica(i).c_serv, v_aplica(i).u_alta, SYSDATE, NULL,NULL);
  24.        
  25.         -- UPDATE
  26.            
  27.         FORALL i IN v_aplica.FIRST .. v_aplica.LAST
  28.         UPDATE aplica A
  29.            SET
  30.               A.u_baja = v_aplica(i).u_baja,
  31.               A.f_baja = SYSDATE
  32.         WHERE
  33.             A.n_serial = v_aplica(i).n_serial
  34.             AND A.f_alta = v_aplica(i).f_alta;
  35.     END;
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)