Вы находитесь на странице: 1из 6

Los cursores permiten recorrer los registros que devuelve una consulta SQL.

Tambin las operaciones INSERT, UPDATE Y DELETE definen un cursor


implcito, denominado SQL.

Atributos de un cursor:

%ROWCOUNT: Cantidad de registros


%FOUND: Indica que hay datos (tipo boolean)
%NOTFOUND: Indica que no hay datos (tipo boolean)
%ISOPEN: Indica si el cursor est abierto (tipo boolean)

Ciclo FOR[editar]
declare
cursor public cur is
select col1, col2
from tabla;
begin
for v_reg in cur loop
dbms_output.put_line ('Col1: '|| v_reg.col1 ||' Col2:
'|| v_reg.col2);
end loop;
end;

La variable v_reg se declara automticamente y tiene validez nicamente dentro


del ciclo FOR.

Es posible definir argumentos al declarar un cursor:

declare
cursor cur (p_col3 col3%type) is
select col1, col2
from tabla
where col3 = p_col3;

v_col3 tabla.col3%type;
begin
v_col3 := 7;

for v_reg in cur (v_col3) loop


dbms_output.put_line ('Col1: '|| v_reg.col1 ||' Col2:
'|| v_reg.col2);
end loop;
end;

OPEN, FETCH y CLOSE[editar]


En ciertos casos, es necesario realizar el procesamiento del cursor paso a paso:

declare
cursor cur is
select col1, col2
from tabla;

v_reg cur%rowtype;
begin
open cur;
loop
fetch cur into v_reg;
exit when cur%notfound;
dbms_output.put_line ('Col1: '|| v_reg.col1 ||' Col2:
'|| v_reg.col2);
end loop;
close cur;
end;

REF CURSOR[editar]
Tambin se pueden definir cursores variables, a diferencia de los estticos
utilizados hasta ahora:

declare
type t_cursor is ref cursor return tabla%rowtype;
v_cursor t_cursor;
v_reg tabla%rowtype;
begin
open v_cursor for
select col1, col2
from tabla;

loop
fetch v_cursor into v_reg;
exit when v_cursor%notfound;
dbms_output.put_line ('Col1: '|| v_reg.col1 ||' Col2:
'|| v_reg.col2);
end loop;
close v_cursor;
end;

Los cursores variables pueden ser pasados como parmetros en procedimientos y


funciones.

Tambin es posible no especificar el tipo de registro retornado por el cursor, lo cual


permite mayor flexiblidad pero impide verificar los tipos en tiempo de compilacin,
lo cual puede dar lugar a errores imprevistos en tiempo de ejecucin.

El siguiente ejemplo ilustra el trabajo con un cursor explicito. Hay que tener en
cuenta que al leer los datos del cursor debemos hacerlo sobre variables del mismo tipo
de datos de la tabla (o tablas) que trata el cursor.

DECLARE
CURSOR cpaises
IS
SELECT CO_PAIS, DESCRIPCION, CONTINENTE
FROM PAISES;

co_pais VARCHAR2(3);
descripcion VARCHAR2(50);
continente VARCHAR2(25);
BEGIN
OPEN cpaises;
FETCH cpaises INTO co_pais,descripcion,continente;
CLOSE cpaises;
END;

Podemos simplificar el ejemplo utilizando el atributo de tipo %ROWTYPE sobre el


cursor.

DECLARE
CURSOR cpaises
IS
SELECT CO_PAIS, DESCRIPCION, CONTINENTE
FROM PAISES;

registro cpaises%ROWTYPE;
BEGIN
OPEN cpaises;
FETCH cpaises INTO registro;
CLOSE cpaises;
END;

El mismo ejemplo, pero utilizando parmetros:

DECLARE
CURSOR cpaises (p_continente VARCHAR2)
IS
SELECT CO_PAIS, DESCRIPCION, CONTINENTE
FROM PAISES
WHERE CONTINENTE = p_continente;

registro cpaises%ROWTYPE;
BEGIN
OPEN cpaises('EUROPA');
FETCH cpaises INTO registro;
CLOSE cpaises;
END;

Manejo del cursor

Por medio de ciclo LOOP podemos iterar a travs del cursor. Debe tenerse cuidado
de agregar una condicin para salir del bucle:

Vamos a ver varias formas de iterar a travs de un cursor. La primera es utilizando


un bucle LOOP con una sentencia EXIT condicionada:

OPEN nombre_cursor;
LOOP
FETCH nombre_cursor INTO lista_variables;
EXIT WHEN nombre_cursor%NOTFOUND;
/* Procesamiento de los registros recuperados */
END LOOP;
CLOSE nombre_cursor;

Aplicada a nuestro ejemplo anterior:


DECLARE
CURSOR cpaises
IS
SELECT CO_PAIS, DESCRIPCION, CONTINENTE
FROM PAISES;

co_pais VARCHAR2(3);
descripcion VARCHAR2(50);
continente VARCHAR2(25);
BEGIN
OPEN cpaises;
LOOP
FETCH cpaises INTO co_pais,descripcion,continente;
EXIT WHEN cpaises%NOTFOUND;
dbms_output.put_line(descripcion);
END LOOP;
CLOSE cpaises;
END;

Otra forma es por medio de un bucle WHILE LOOP. La instruccin FECTH aparece
dos veces.

OPEN nombre_cursor;
FETCH nombre_cursor INTO lista_variables;
WHILE nombre_cursor%FOUND
LOOP
/* Procesamiento de los registros recuperados */
FETCH nombre_cursor INTO lista_variables;
END LOOP;
CLOSE nombre_cursor;

DECLARE
CURSOR cpaises
IS
SELECT CO_PAIS, DESCRIPCION, CONTINENTE
FROM PAISES;

co_pais VARCHAR2(3);
descripcion VARCHAR2(50);
continente VARCHAR2(25);
BEGIN
OPEN cpaises;
FETCH cpaises INTO co_pais,descripcion,continente;
WHILE cpaises%found
LOOP
dbms_output.put_line(descripcion);
FETCH cpaises INTO co_pais,descripcion,continente;
END LOOP;
CLOSE cpaises;
END;

Por ltimo podemos usar un bucle FOR LOOP. Es la forma ms corta ya que el cursor
es implicitamente se ejecutan las instrucciones OPEN, FECTH y CLOSE.

FOR variable IN nombre_cursor LOOP


/* Procesamiento de los registros recuperados */
END LOOP;

BEGIN
FOR REG IN (SELECT * FROM PAISES)
LOOP
dbms_output.put_line(reg.descripcion);
END LOOP;
END;

Вам также может понравиться