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
PROCEDURE APPAnual IS TYPE t_aplica IS TABLE OF APLICA%ROWTYPE; DECLARE v_aplica t_aplica; BEGIN -- Recupero todos los registros del año anterior SELECT AP.id, AP.numero, AP.cont, AP.n_serial, AP.c_serv, AP.u_alta, AP.f_alta, AP.u_baja,AP.f_baja BULK COLLECT INTO v_aplica FROM APLICA AP WHERE TO_CHAR(AP.F_ALTA,'YYYY') = TO_CHAR(SYSDATE,'YYYY')-1 AND AP.U_BAJA IS NULL AND AP.F_BAJA IS NULL; -- INSERT FORALL i IN v_aplica.FIRST .. v_aplica.LAST INSERT INTO APLICA( AP.id, AP.numero, AP.cont, AP.n_serial, AP.c_serv, AP.u_alta, AP.f_alta, AP.u_baja,AP.f_baja) VALUES( app_seq.NEXTVAL, v_aplica(i).numero, v_aplica(i).cnt, v_aplica(i).n_serial, v_aplica(i).c_serv, v_aplica(i).u_alta, SYSDATE, NULL,NULL); -- UPDATE FORALL i IN v_aplica.FIRST .. v_aplica.LAST UPDATE aplica A SET A.u_baja = v_aplica(i).u_baja, A.f_baja = SYSDATE WHERE A.n_serial = v_aplica(i).n_serial AND A.f_alta = v_aplica(i).f_alta; END;