INTRODUCCIÓN AL LENGUAJE DE PROGRAMACIÓN PL/SQL
CURSORES
I
NTRODUCCIÓNComo vimos en la práctica de procedimientos dentro de
PL/SQLla orden
SELECTno devuelve
más de una fila. Si deseamos obtener más de un valor utilizamos un cursor explícito para
extraer individualmente cada fila.
Un cursor es un área de memoria utilizada para realizar operaciones con los registros
devueltos tras ejecutar una sentencia
SELECT. Existen dos tipos:
y Implícitos
y Explícitos
Su sintaxis es la siguiente:
CURSOR nombreCursor IS ordenSelect
El cursor explícito se abre mediante la siguiente sintaxis:
OPEN nombreCursor;
La extracción de los datos y su almacenamiento en variables
PL/SQLse realiza utilizando la
siguiente sintaxis:
FETCH nombreCursor INTO listaVariables; FETCH nombreCursor INTO registroPL/SQL;
Para cerrarlo utilizamos
CLOSE nombreCursor;
Entre los atributos de los cursores explícitos tenemos
%FOUNDy
%NOTFOUNDpara controlar
si la última orden
FETCHdevolvió o no una fila,
%ISOPENpara saber si el cursor está abierto
o no; y
%ROWCOUNTque devuelve el número de filas extraídas por el cursor hasta ahora.
Enseguida se mostrarán ejemplos del uso de un cursor.
E
JEMPLO1.
Consideremos la creación de la siguiente tabla:
CREATE TABLE estudiante( id NUMBER(5) PRIMARY KEY, nombre CHAR(20),
apellido CHAR(20), especialidad CHAR(30), avCreditos NUMBER);
Enseguida cree un procedimiento para insertar valores a la entidad
ESTUDIANTE, generada
anteriormente y agregue los siguientes datos:
ID NOMBRE APELLIDO ESPECIALIDAD AVCREDITOS
1 Luis Ramirez Computacion 10
2 Margarita Mendoza Historia 8
3 Patricia Muñoz Computacion 20
4 Tomas Tapia Musica 15
5 Alejandro Perez Nutricion 25
6 Ester Estrada Nutricion 18
7 Rita Rodriguez Musica 25
8 Rosa Ramirez Historia 9
9 David Ortega Musica 22
10 Juan Alvarez Computacion 19
E
JEMPLO2.
Cree un cursor sencillo que muestre los nombres y apellidos de los alumnos
ordenados por su
especialidad.Para probarlo recuerde activar su variable de entorno para la
salida
(SET SERVEROUTPUT ON;).DECLARE
CURSOR estudReg IS
-- declaramos el cursor
SELECT * FROM estudiante ORDER BY especialidad;
rEstud estudiante%ROWTYPE;
--variable de tipo registro
BEGIN
OPEN estudReg;
--abrimos el cursor
FETCH estudReg INTO rEstud;
DBMS_OUTPUT.PUT_LINE('Resultado : ');
WHILE estudReg%FOUND LOOP
--usamos un bucle para capturar los
registros
DBMS_OUTPUT.PUT_LINE(rEstud.especialidad||' '||rEstud.nombre||' ' ||restud.apellido);
FETCH estudReg INTO rEstud; END LOOP;
CLOSE estudReg;
-- cerramos el cursor
END; /
Con el fin de simplificar los pasos necesarios para configurar y procesar un cursor podemos
usar un bucle de cursor
FOR.E
JEMPLO3.
En este ejemplo se ordenan los estudiantes por su nombre utilizando un
cursor
FOR.DECLARE
CURSOR estudReg IS SELECT * FROM estudiante ORDER BY nombre;
BEGIN
DBMS_OUTPUT.PUT_LINE('Resultado : '); FOR rEstud IN estudReg LOOP
DBMS_OUTPUT.PUT_LINE(rEstud.id||' '||rEstud.nombre||' '||restud.apellido); END LOOP;
END; /
También podemos declarar cursores con parámetros para definir un criterio de selección.
E
JEMPLO4.
Se muestra la utilización de cursores con parámetros para obtener aquellos
estudiantes cuyo número de registro es mayor o igual a 7.
DECLARE
CURSOR espeEstud(vid NUMBER) IS SELECT id, nombre ,apellido, especialidad FROM estudiante
WHERE id>=vid; BEGIN
DBMS_OUTPUT.PUT_LINE('Estudiantes seleccionados '); FOR EstReg in espeEstud(7) LOOP
DBMS_OUTPUT.PUT_LINE(EstReg.id||' '||EstReg.especialidad||' ' || EstReg.nombre);
END LOOP; END;
E
JEMPLO5.
Ahora vamos a crear un cursor para seleccionar los datos de los estudiantes que
tienen la especialidad Historia y guardarlos en una tabla llamada
TEMPORAL.Primero debemos crear la tabla temporal donde se guardará la información.
CREATE TABLE temporal( columnaNumerica NUMBER, columnaCaracter VARCHAR(60) );
Después creamos el cursor.
DECLARE
vClaveEst estudiante.id%TYPE; vNombre estudiante.nombre%TYPE; vApellido estudiante.apellido%TYPE;
--Creamos el cursor para almacenar a los estudiantes cuya especialidad es
HistoriaCURSOR cursorEstudiantesHistoria IS SELECT id,nombre,apellido FROM estudiante WHERE especialidad='Historia'; BEGIN
-- Abrimos el cursor
OPEN cursorEstudiantesHistoria; LOOP-- Recuperamos la información de los estudiantes
FETCH cursorEstudiantesHistoria INTO vClaveEst, vNombre, vApellido;
-- Salimos del bloque al terminar
EXIT WHEN cursorEstudiantesHistoria%NOTFOUND;
--Guardamos en una tabla temporal
INSERT INTO temporal (columnanumerica,columnacaracter) VALUES(vClaveEst, vNombre || ' ' || vApellido); END LOOP;
-- Cerramos el cursor
CLOSE cursorEstudiantesHistoria; COMMIT; END; /V
ARIABLES DE TIPO CURSORLas variables de cursor son análogas a las variables
PL/SQL, ya que pueden contener diferentes
valores en tiempo de ejecución. La sintaxis para definir un tipo de variable de cursor es la
siguiente:
TYPE nombreTipo IS REF CURSOR RETURN tipoRetorno;
El nuevo nombre de referencia
nombreTipoy
tipoRetornoes un tipo de registro que será
devuelto por la variable del cursor. Las variables de cursor pueden no tener cláusula
RETURN.Se puede realizar la apertura de una variable de cursor, previamente definida, para una
consulta mediante la sintaxis:
OPEN variableCursor FOR ordenSeleccionConsulta
Las variables de cursor se cierran con la orden
CLOSE.EJEMPLO 6.
El siguiente ejemplo utiliza variables de cursor para seleccionar estudiantes
dependiendo de la especialidad que se desee.
CREATE OR REPLACE PROCEDURE utilizaCursor(espe IN VARCHAR2) AS
TYPE cursorEstudiantes IS REF CURSOR; vCursor cursorEstudiantes;
vClaveEst estudiante.id%TYPE; vNombre estudiante.nombre%TYPE; vApellido estudiante.apellido%TYPE;
vEspecialidad estudiante.especialidad%TYPE := espe; BEGIN
OPEN vCursor FOR
SELECT id,nombre,apellido FROM estudiante WHERE especialidad=vEspecialidad;
LOOP
-- Recuperamos la información de los estudiantes
FETCH vCursor INTO vClaveEst, vNombre, vApellido;
-- Salimos del bloque al teminar
EXIT WHEN vCursor%NOTFOUND;
--Guardamos en una tabla temporal
INSERT INTO temporal (columnanumerica,columnacaracter) VALUES(vClaveEst, vNombre || ' ' || vApellido);
END LOOP;
CLOSE vCursor; COMMIT;
END utilizaCursor; /
Realice las siguientes actividades y compruebe el resultado.
a) Elimine el contenido de la tabla
TEMPORAL.DELETE FROM temporal;
b) Ejecute el procedimiento indicando la especialidad del estudiante que desea encontrar.
EXEC utilizaCursor(‘Nutricion’);
c) Observe el resultado obtenido en la tabla
TEMPORAL.
SELECT * FROMtemporal;
V
ARIABLES DE TIPO REGISTRORecordemos que en un bloque
PL/SQLse puede utilizar el atributo
%ROWTYPEpara declarar
variables de tipo registro. Estas variables que son declaradas usando el atributo
%ROWTYPEautomáticamente obtienen los nombres de campos y los tipos que corresponden con los de la
tabla referenciada.
Introduzca el siguiente bloque
PL/SQL anónimoque corresponde a la tabla
ESTUDIANTE,en
la cual se proporcionan todos los datos del estudiante cuya clave es 6.
DECLARE
SeleccionEstudiantes estudiante%ROWTYPE; BEGIN
SELECT * INTO seleccionEstudiantes FROM estudiante WHERE id=6;
DBMS_OUTPUT.PUT_LINE(‘Apellido estudiante: ‘ || seleccionEstudiantes.apellido); DBMS_OUTPUT.PUT_LINE(‘Especialidad: ‘ || seleccionEstudiantes.especialidad); END; /
Se obtiene la siguiente salida:
Apellido estudiante: Estrada Especialidad: Nutricion