You are on page 1of 32

ADMINISTRACION EN

BASES DE DATOS

CURSORES

Facultad de ingeniería

Profesor: Alexis Rojas Cordero 1


OBJETIVOS

• Aprender a crear y usar procedimientos


almacenados y utilizar cursores dentro de bloques
PL/SQL.
Usan

Controlar el fin de los cursores

Alexis Rojas Cordero


Página –2–
INTRODUCCION
Qué es un cursor ?
Los cursores son punteros a unas zonas de memoria llamadas áreas de
contexto en las cuales se almacena información acerca del resultado de una
consulta

Mediante este puntero (cursor), un programa PL/SQL puede controlar Usan


el
área de contexto y manejar el conjunto de registros devueltos por una
consulta.

 Oracle maneja dos tipos de cursores. Implícitos y Explícitos.

Alexis Rojas Cordero


Página –3–
CURSORES
Cursores Implícitos.
Son cursores declarados implícitamente por Oracle para todas las
sentencias DML y PL-SQL. Oracle abre implícitamente el cursor para
procesar cada instrucción. Devuelve o una fila o un valor

Usan
En un cursor implícito no se puede usar OPEN, FETCH ni CLOSE.

1125 Juan Valdés


2343 Marta Morales

Cursor 3045 Luis flores Fila del cursor


4520 Pedro Perez
5063 Manuel Bolaños

Conjunto activo
Alexis Rojas Cordero
Página –4–
CURSORES
Cursores Implícitos. Deben tenerse en cuenta los siguientes puntos cuando
se utilizan cursores implícitos:

 Con cada cursor implícito debe existir la palabra clave INTO.


 Las variables que reciben los datos devueltos por el cursor tienen que contener el
mismo tipo de dato que las columnas de la tabla.

 Los cursores implícitos solo pueden devolver una única fila. En caso de que se
devuelva más de una fila (o ninguna fila) se producirá una excepción. Usan

Select codigo, nombre, apellido


1125 Juan Valdés
2343 Marta Morales into cod, nom, ape
Cursor 3045 Luis flores
form emp
4520 Pedro Perez
5063 Manuel Bolaños
where cod = 3045

Alexis Rojas Cordero


Página –5–
CURSORES
Ejemplo de Cursores Implícitos.
Los cursores implícitos
(dentro de un pl/sql) sólo
pueden devolver una fila, por
lo que pueden producirse
determinadas excepciones.

Las más comunes queUsan


se
pueden encontrar son
no_data_found y
too_many_rows.

Alexis Rojas Cordero


Página –6–
Excepciones de Cursores Implícitos.
EXCEPCION EXPLICACION
NO_DATA_FOUND Una sentencia SELECT INTO no devolvió valores o el programa
referenció un elemento no inicializado en una tabla indexada
VALUE_ERROR Ocurrió un error aritmético, de conversión o truncamiento. Por
ejemplo, sucede cuando se intenta calzar un valor muy grande
dentro de una variable más pequeña
TOO_MANY_ROWS Una sentencia SELECT INTO devuelve más de una fila
Usan
INVALID_CURSOR El programa intentó efectuar una operación no válida sobre un
cursor
ZERO_DIVIDE El programa intentó efectuar una división por cero

DUP_VAL_ON_INDEX El programa intentó almacenar valores duplicados en una


columna que se mantiene con restricción de integridad de un
índice único (unique index
OTHERS Cualquier otro error

Alexis Rojas Cordero


Página –7–
CURSORES EXPLICITOS
 Son los cursores que son declarados y controlados por el programador.
Se utilizan cuando la consulta devuelve un conjunto de registros.

Ocasionalmente también se utilizan en consultas que devuelven un único


registro por razones de eficiencia. Son más rápidos

Usan
Pasos necesarios para procesar un cursor:

• Declaración de un CURSOR.
• Apertura del CURSOR para una consulta.
• Recuperar los resultados de la variables PL/SQL.
• Cierre del CURSOR.

Alexis Rojas Cordero


Página –8–
CURSORES EXPLICITOS

Cierra el
Crea el cursor y
área para descarga la
el cursor NO memoria

DECLARE OPEN FETCH VACIO? Usan


CLOSE

Carga la
Identifica fila en Verifica
el conjunto las vbles si quedan
activo con filas para
INTO cargar

Alexis Rojas Cordero


Página –9–
DECLARACION - CURSORES EXPLICITOS

DECLARE
CURSOR <<nombre_cursor>> IS
SELECT <<lista de campos >>
FROM << nombre_tabla >>Usan
[WHERE << condiciones >> ];

BEGIN …

Alexis Rojas Cordero


Página –10–
DECLARACION - CURSORES EXPLICITOS
Ejemplo:

DECLARE
CURSOR cur_estudiantes IS Usan
SELECT nombre, apellidos
FROM estudiantes;

v_fila_estud cur_estudiantes%ROWTYPE;

Alexis Rojas Cordero


Página –11–
DECLARACION - CURSORES EXPLICITOS
Ejemplo: SET SERVEROUTPUT ON;
DECLARE
CURSOR cur_estudiantes IS
Este es un SELECT nombre, apellidos
ejemplo de un FROM estudiantes
WHERE rownum <= 5; -- termina def. cursor
cursor manual v_fila_estud cur_estudiantes%ROWTYPE;
donde se abre, se
lee con FETCH, BEGIN
OPEN cur_estudiantes ; Usan
se procesa LOOP
(dentro del loop) FETCH cur_estudiantes INTO v_fila_estud ;
y se cierra el EXIT WHEN cur_estudiantes %NOTFOUND;
cursor cuando se DBMS_OUTPUT.PUT_LINE(Nombre: '||
v_fila_estud .nombre ||´ ‘||
termina el loop. v_fila_estud. apellidos);
END LOOP;
CLOSE cur_estudiantes
END;

Alexis Rojas Cordero


Página –12–
EJEMPLO DE CURSORES EXPLICITOS
DECLARE
CURSOR emp_cursor IS
SELECT cod_empleado, nombre_empleado
FROM emp;

CURSOR dpto_cursor IS
SELECT *
FROM departamentos Usan
WHERE cod_dpto > 10;
V_trabajo number(9);
BEGIN

Nota: La cláusula SELECT de los cursores explícitos, no incluye la


cláusula INTO. Esta es propia de FETCH

Alexis Rojas Cordero


Página –13–
APERTURA DE CURSORES EXPLICITOS
La sintaxis para abrir un cursor es:

OPEN nombre_cursor;

Al abrir un cursor suceden tres cosas:


1.- Se examinan los valores de las variables aceptadas. Usan
2.- Se determina el conjunto activo, basándose en los valores de
dichas variables
3.- Se hace apuntar el puntero del conjunto activo a la primera
fila.

Alexis Rojas Cordero


Página –14–
EJEMPLO DE CURSORES EXPLICITOS
El conjunto activo: es el conjunto de filas que satisfacen los criterios de la
consulta, que se determina en el momento de abrir un cursor.

La cláusula WHERE se evalúa para la tabla o tablas referenciadas en la cláusula


FROM de la consulta, y todas las filas para las cuales se evalúe la condición como
TRUE, son añadidas al conjunto activo.

También se establece un puntero al conjunto activo en el momento de Usan


abrir el
cursor. Este puntero indica cuál es la siguiente fila que el cursor extraerá.

Es legal abrir un cursor que ya esté abierto. PL/SQL ejecutará implícitamente un
CLOSE antes de re-abrir el cursor con la segunda orden OPEN.

También puede haber más de un cursor abierto al mismo tiempo.

Alexis Rojas Cordero


Página –15–
Extracción de los datos de un CURSOR
La cláusula INTO de la consulta es parte de la orden
FETCH. Dicha orden tiene dos formas posibles:

FETCH nombre_cursor INTO lista_variables;


FETCH nombre_cursor INTO registro_PL/SQL;
Usan
Nombre_cursor: Identifica a un cursor abierto y ya
declarado.

Lista_variables: Es una lista de variables PL/SQL


previamente declaradas y separadas por comas.

Alexis Rojas Cordero


Página –16–
Extracción de los datos de un CURSOR
EJEMPLO:
DECLARE
v_cod_emp emp.cod_empleado%TYPE;
v_nom_emp emp.nombre_empleado%TYPE;

CURSOR emp_cursor IS
SELECT cod_empleado, nombre_empleado
FROM emp;
Usan
BEGIN
OPEN emp_cursor;
FOR i IN 1..5 LOOP
FETCH emp_cursor INTO v_cod_emp, v_nom_emp;
...
...
END LOOP;
CLOSE emp_cursor;
END;

Alexis Rojas Cordero


Página –17–
Extracción de los datos de un CURSOR
Tanto para la lista de variables como para el registro
PL-SQL, la variable o variables de la cláusula INTO
deben ser compatibles en cuanto a tipo con la lista de
selección de la consulta.

Después de cada FETCH, se incrementa el punteroUsan


activo, para que apunte a la siguiente fila, así cada
FETCH devolverá filas sucesivas del conjunto activo,
hasta que se devuelve el conjunto completo, es decir
hasta que se llega al final del cursor.

Alexis Rojas Cordero


Página –18–
CIERRE de un CURSOR
Cuando se ha terminado de extraer el
conjunto activo, debe cerrarse el cursor.

Esta acción informa a PL/SQL de que el


programa ha terminado de utilizar el Usan
cursor, y de que se pueden liberar los
recursos con él asociados.

Alexis Rojas Cordero


Página –19–
CIERRE de un CURSOR
Estos recursos incluyen las áreas de almacenamiento
empleadas para contener el conjunto activo, así como
cualquier espacio temporal utilizado en la determinación de
dicho conjunto.

La sintaxis para el cierre del cursor es: Usan

CLOSE nombre_cursor;
Si intentamos cerrar un cursor que ya está cerrado nos
daría un error ORA-1001.

Alexis Rojas Cordero


Página –20–
EXCEPCIONES CURSORES EXPLICITOS

Usan

Alexis Rojas Cordero


Página –21–
ATRIBUTO %ISOPEN
Una fila de un cursor solamente puede ser leída cuando el cursor está
abierto.
El atributo %ISOPEN se usa en programas muy grandes solo para saber si
el cursor está abierto. Retorna un booleano (TRUE or FALSE)

Ejemplo:

Usan
IF NOT emp_cursor%ISOPEN THEN
OPEN emp_cursor;
END IF;
LOOP
FETCH emp_cursor . . .

Alexis Rojas Cordero


Página –22–
%NOTFOUND y %ROWCOUNT
En los cursores EXPLICITOS, las excepciones se manejan
con las condiciones de atributos.

%FOUND nos indica que EN el cursor SI hay registros


para leer.
Usan
%NOTFOUND nos indica que EN el cursor no habían o ya se
acabaron los registros para leer o seguir leyendo.

%ROWCOUNT, nos lleva el contador de los registros


leídos desde el cursor.

Alexis Rojas Cordero


Página –23–
EJEMPLO PRACTICO %NOTFOUND

Usan

Alexis Rojas Cordero


Página –24–
EJEMPLO DE %ROWCOUNT y %NOTFOUND
DECLARE
v_cod_empleado emp.cod_empleado%TYPE;
v_nom_empleado emp.nombre_empleado%TYPE;

CURSOR emp_cursor IS
SELECT cod_empleado, nombre_empleado
FROM emp;
BEGIN
OPEN emp_cursor; Usan
LOOP
FETCH emp_cursor INTO v_cod_empleado, v_nom_empledo;
EXIT WHEN emp_cursor%ROWCOUNT > 10 OR
emp_cursor%NOTFOUND;
...
END LOOP;
CLOSE emp_cursor;
END;

Alexis Rojas Cordero


Página –25–
ATRIBUTO %FOUND
El atributo %FOUND se usa para saber si un cursor que está abierto
tiene registros. Se utiliza mucho en los cursores automáticos.

Usan

Alexis Rojas Cordero


Página –26–
ATRIBUTO %FOUND
Se inicia el cursor
automáticamente

La instrucción
Usan
IF c_obli_deudor%FOUND
Se encarga de verificar
Si el conjunto activo
Tiene elementos.
Si es TRUE entonces
Procesa lo que está en
azul

Alexis Rojas Cordero


Página –27–
CURSORES EXPLICITOS Y REGISTROS
Sirven para procesar registros de un conjunto activo (Cursor) leyendo los
datos del cursor y cargando cada registro del cursor en una estructura de
registro. Ejemplo:

DECLARE
CURSOR emp_cursor IS
SELECT cod_empleado, nombre_empleado FROM emp;
emp_registro emp_cursor%ROWTYPE;
BEGIN
OPEN emp_cursor; Usan
LOOP
FETCH emp_cursor INTO emp_registro;
EXIT WHEN emp_cursor%NOTFOUND;
INSERT INTO lista_temp (cod_lista, nom_lista)
VALUES(emp_registro.cod_empleado, emp_registro.nombre_empleado);
END LOOP;
COMMIT;
CLOSE emp_cursor;
END;

Alexis Rojas Cordero


Página –28–
CURSORES AUTORMATICOS
SINTAXIS.

FOR nombre_registro IN nombre_cursor LOOP


Sentencia1;
Sentencia2;
...
END LOOP -- fin del cursor

• El cursor FOR .. IN .. LOOP es un atajo para procesar cursores explícitos


Usan
• Abre, lee y cierra automáticamente el cursor cuando se terminan los datos del
conjunto activo.
• El registro es declarado implícitamente.

Nombre_registro Es declarado automáticamente.


Nombre_cursor. Es el nombre que se le dá al cursor para poderlo referenciar

Nota: la mayor utilidad del %FOUND se ve en los cursores automáticos

Alexis Rojas Cordero


Página –29–
CURSORES AUTORMATICOS
EJEMPLO:
SET SERVERTOUTPUT ON
DECLARE
CURSOR emp_cursor IS
SELECT cod_empleado, nombre_empleado,sueldo
FROM emp;

BEGIN
FOR registro_emp IN emp_cursor LOOP
IF emp_cursor%FOUND THEN Usan
IF registro_emp.sueldo > 3800 THEN
DBMS_OUT.PUT_LINE(‘ Trabajador ‘|| registro_emp.nomre_empleado ||
‘ tiene un sueldo de: ‘ || registro_emp.sueldo); ado);
END IF; -- endif del registro
END IF, -- ENDIF del emp_cursor
END LOOP; Cierre automático del cursor
END;

Alexis Rojas Cordero


Página –30–
CURSORES AUTORMATICOS con SUBQUERYS
SET SERVERTOUTPUT ON
BEGIN

FOR emp_registro IN (SELECT cod_empleado, nombre_empleado, sueldo ROM emp)


LOOP
IF registro_emp.sueldo > 3800 THEN
DBMS_OUT.PUT_LINE(‘ Trabajador ‘|| registro_emp.nomre_empleado ||
‘ tiene un sueldo de: ‘ || registro_emp.sueldo); ado);
END IF; -- endif del registro Usan
END LOOP; Cierre automático del cursor
END;

NOTA: Este tipo de cursores es para personas con mucha experiencia


y se usa para procesos ocasionales.
No usa el DECLARE y el control de si está vacío
se hace por programación

Alexis Rojas Cordero


Página –31–
EJERCICIOS parte 1.
1. Cree un programa capra2100.sql para trabajar un CURSOR EXPLICITO
que se llame emp_cursor. Defina las variables de trabajo y selecione
el nombre, el sueldo y la comision para los empleados que tienen
comisión mayor del 15%. Desplieque luego mediante la opción
DBMS_OUT.PUT_LINE todos los empleados con del conjunto activo
que usted selecionó. Mueste el nombre, el sueldo y la comisión. Use la
opcion LOOP…END LOOP
2. Modifique el programa capra2100 como capra2101.sql para desplegar
mediante un cursor explicito que use un registro en vez de variables
de trabajo, con el control WHILE para imprimir con DBMS todos los
empledos que tienen comisión menor del 15%.
3. Cree un programa capra2102.sql para imprimir con
DBMS.OUTPUT_PUT_LINE todos los empleados que tiene más de 300
meses de edad. Calcule la prima de seguro de vida multiplicando el
sueldo por el 5% para los que tienen menos de 100 meses y por 10%
para los mayores de 100 meses. Use la estructura de del cursor
FOR..IN..LOOP.

Alexis Rojas Cordero


Página –32–