miércoles, 10 de octubre de 2007

Cursores PL/SQL notación OPEN...FETCH...CLOSE

Esta notación de cursores PL/SQL nos brinda flexibilidad agregando a cambio cierta complejidad. Declaramos el cursor y la sentencia SELECT asociada en la línea 4. Esta declaración es independiente de la ejecución de la sentencia y del recupero de sus filas. La variable Registro es declarada en forma explícita en la línea 8. Abrimos explícitamente el cursor en la línea 10 con la instrucción OPEN. Este es el momento donde se seleccionan la filas que luego seán recuperadas. Si se agregan filas a la tabla antes de ser recuperadas no serán mostradas. La foto de los datos a recuperar se toma en un punto en el tiempo y los cambios posteriores no son reflejados. Recuperamos las filas seleccionadas con la instrucción FETCH de la línea 12. Cada FETCH recupera una fila. Luego preguntamos en la línea 13 si no se encontraron filas para procesar, si es así salimos el ciclo de procesamiento de filas. Mostramos los valores de cada fila recuperada en la línea 16. Cerramos el cursor en forma explícita en la línea 21.
SQL> conn fernandez/fernandez
Conectado.

SQL> create or replace
2 PROCEDURE CURSOR_OPEN_FETCH
3 IS
4 CURSOR CursorVistas
5 IS (SELECT OWNER, VIEW_NAME
6 FROM ALL_VIEWS
7 WHERE OWNER = 'SYS'
8 AND VIEW_NAME LIKE 'ALL_TAB%');
9 Registro CursorVistas%ROWTYPE;
10 BEGIN
11 OPEN CursorVistas;
12 LOOP
13 FETCH CursorVistas INTO Registro;
14 IF CursorVistas%NOTFOUND THEN
15 EXIT;
16 END IF;
17 DBMS_OUTPUT.PUT_LINE('ESQUEMA: ' ||
18 Registro.OWNER ||
19 ' VISTA: ' ||
20 Registro.VIEW_NAME);
21 END LOOP;
22 CLOSE CursorVistas;
23 END CURSOR_OPEN_FETCH;
24 /

Procedimiento creado.
Verificamos la existencia del procedimiento creado.
SQL> DESCRIBE CURSOR_OPEN_FETCH
PROCEDURE cursor_open_fetch
Verificamos si están habilitados los mensajes por pantalla. Si no lo están, los habilitamos.
SQL> SHOW SERVEROUTPUT
serveroutput OFF

SQL> SET SERVEROUTPUT ON
Ejecutamos el procedimiento y vemos los mensajes en pantalla asociados a la recuperación de cada fila del cursor.
SQL> EXECUTE CURSOR_OPEN_FETCH
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

También podemos leer una descripción amplia sobre cómo decide el motor de la base de datos qué datos mostrar al ejecutar el OPEN del cursor en la documentación estandar de Oracle:

Manual: Oracle Database Concepts
Capítulo: 13 Data Concurrency and Consistency
Título: How Oracle Manages Data Concurrency and Consistency
Subtítulo: Statement-Level Read Consistency

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...