jueves, 11 de octubre de 2007

Cursores PL/SQL notación FETCH...BULK COLLECT INTO...

Esta notación nos permite recuperar todas las filas asociadas a la sentencia SELECT que representa el cursor con la ejecución de una única instrucción FETCH.
Resumiremos linea a línea el código fuente del procedimiento del ejemplo:

Línea 2: Inicio del procedimiento.
Línea 4: Declaramos un tipo de dato de array o vector que almacena filas de la tabla ALL_VIEWS y lo llamamos TipoArrayRegistros. Es decir, cada elemento del array permite almacenar todos los valores de una fila de la tabla ALL_VIEWS. Cada elemento del array contiene tantos campos como columnas tiene la tabla, con los mismos nombres y tipos de dato.
Línea 5: Declaramos la variable ArrayRegistros del tipo de datos TipoArrayRegistros.
Líneas 7 a 10: Declaramos el cursor de nombre CursorVistas y lo asociamos a la sentencia SELECT que recupera las filas.
Línea 11: Declaramos la variable indice de tipo de dato entero. La utilizaremos para hacer referencia a los valores que contiene el array o vector.
Línea 14: Abrimos el cursor. Este paso selecciona las filas de la tabla que evalúan verdadera la condición de la sentencia SELECT. Si cambian los valores de las filas antes de ser recuperadas, estos cambios no se verán reflejados. Tomamos la foto de los datos a recuperar en este punto en el tiempo. No se consideran modificaciones posteriores.
Línea 15: Recuperamos las filas que cumplen la condición de la sentencia SELECT con la instrucción FETCH. El BULK COLLECT INTO permite asignar todas las filas recuperadas a un array o vector. Cada elemento del array contiene una fila recuperada. Los elementos están formados por una estructura de campos con nombres y tipos de datos equivalentes a las columnas seleccionadas.
Línea 16: Cerramos el cursor. Liberamos los recursos en memoria asociados a la sentencia SELECT.
Línea 18: Asignamos a la variable indice la posición del primer elemento almacenado en el array o vector. Si no contiene elementos se asigna el valor NULL.
Línea 19 a 26: Mientras la variable indice sea distinta de NULL iteramos dentro del ciclo definido por el LOOP...END LOOP. Por cada ciclo mostramos en pantalla con la instrucción DBMS_OUTPUT.PUT_LINE el contenido de los campos OWNER y VIEW_NAME en la posición indice del array. Luego asignamos a la variable indice la siguiente posición del array que contiene una fila. Si no hay mas filas en el array se asigna NULL. Al evaluarse la condición de WHILE (indice IS NOT NULL) se corta la iteración de los ciclos.
Línea 28: Fin del procedimiento.

SQL> CONNECT FERNANDEZ/FERNANDEZ
Conectado.

SQL> create or replace
2 PROCEDURE FETCH_BULK_COLLECT_INTO
3 IS
4 TYPE TipoArrayRegistros IS TABLE OF ALL_VIEWS%ROWTYPE;
5 ArrayRegistros TipoArrayRegistros;
6
7 CURSOR CursorVistas IS SELECT *
8 FROM ALL_VIEWS
9 WHERE OWNER = 'SYS'
10 AND VIEW_NAME LIKE 'ALL_TAB%';
11 indice PLS_INTEGER;
12 BEGIN
13
14 OPEN CursorVistas;
15 FETCH CursorVistas BULK COLLECT INTO ArrayRegistros;
16 CLOSE CursorVistas;
17
18 indice := ArrayRegistros.FIRST;
19 WHILE (indice IS NOT NULL)
20 LOOP
21 DBMS_OUTPUT.PUT_LINE('ESQUEMA: ' ||
22 ArrayRegistros(indice).OWNER ||
23 ' VISTA : ' ||
24 ArrayRegistros(indice).VIEW_NAME);
25 indice := ArrayRegistros.NEXT(indice);
26 END LOOP;
27
28 END FETCH_BULK_COLLECT_INTO;
29 /

Procedimiento creado.

SQL> SET SERVEROUTPUT ON

SQL> EXECUTE FETCH_BULK_COLLECT_INTO;
ESQUEMA: SYS VISTA : ALL_TABLES
ESQUEMA: SYS VISTA : ALL_TAB_COLS
ESQUEMA: SYS VISTA : ALL_TAB_COLUMNS
ESQUEMA: SYS VISTA : ALL_TAB_COL_STATISTICS
ESQUEMA: SYS VISTA : ALL_TAB_COMMENTS
ESQUEMA: SYS VISTA : ALL_TAB_HISTOGRAMS
ESQUEMA: SYS VISTA : ALL_TAB_MODIFICATIONS
ESQUEMA: SYS VISTA : ALL_TAB_PARTITIONS
ESQUEMA: SYS VISTA : ALL_TAB_PRIVS
ESQUEMA: SYS VISTA : ALL_TAB_PRIVS_MADE
ESQUEMA: SYS VISTA : ALL_TAB_PRIVS_RECD
ESQUEMA: SYS VISTA : ALL_TAB_STATISTICS
ESQUEMA: SYS VISTA : ALL_TAB_STATS_HISTORY
ESQUEMA: SYS VISTA : ALL_TAB_SUBPARTITIONS


Procedimiento PL/SQL terminado correctamente.

SQL>
Podemos leer este tema en la documentación estandar de Oracle:

Manual: Oracle Database PL/SQL User's Guide and Reference
Capítulo: 6 Performing SQL Operations from PL/SQL
Título: Managing Cursors in PL/SQL
Subtítulo: Explicit Cursors
Párrafo: Fetching Bulk Data with a Cursor

Entradas relacionadas:
PL/SQL Tutorial
Cursores PL/SQL notación SELECT..INTO
Cursores PL/SQL notación FOR...LOOP
Cursores PL/SQL notación CURSOR...FOR...LOOP
Cursores PL/SQL notación OPEN...FETCH...CLOSE
Cursores PL/SQL notación FETCH...BULK COLLECT INTO...

1 comentario:

Anónimo dijo...

Very good example !!! , I'll use in my oracle applicatios.
Regards.
Javier.