Comenzamos a explicar los cursores de PL/SQL. Veremos los cursores explícitos, sus atributos y las variables de acoplamiento .
Hasta ahora hemos utilizado cursores implícitos, cuando devolvíamos el resultado de una select mediante la clausula into a una variable. Pero esto es un problema cuando el resultado de una subconsulta nos devolvía varias filas, porque esto nos daria un error al ejecutar la consulta
Para que no nos salte un error en estos casos debemos utilizar los cursores explícitos.
Cursores explícitos
Los cursores explícitos los utilizamos cuando tenemos consultas que nos devuelven más de una fila.Tenemos 4 operaciones básicas para trabajar con un cursor explícito.
- Declaración del cursor: lo tenemos que declarar en la zona de declaraciones, con el siguiente formato: CURSOR <nombrecursor> IS <sentencia SELECT>;
- Apertura del cursor: Deberá colocarse en la zona de instrucciones, con el siguiente formato:
OPEN <nombrecursor>;
Al hacerlo se ejecuta automáticamente la sentencia select y sus resultados se almacenan en las estructuras internas de memoria manejadas por el cursor. - Recogida de información: Para recuperar la información anteriormente guardada en las estructuras de memoria interna tenemos que usar el siguiente formato:
FETCH <nombrecursor> INTO {<variable> | <listavariables>};
Si tenemos una única variable que recoge los datos de todas las columnas, el formato de la variable seria el siguiente:
<variable> <nombrecursor>%ROWTYPE;
Si tenemos una lista de variables, cada una recogerá la columna correspondiente de la cláusula select, por lo que serán del mismo tipo que las columnas. - - Cierre del cursor:
CLOSE <nombrecursor>;
DECLARE
CURSOR C1 IS SELECT nombre, apellido FROM arbitro;
Vnom VARCHAR2(12);
Vape VARCHAR2(20);
BEGIN
OPEN C1;
LOOP
FETCH C1 INTO Vnom, Vape;
EXIT WHEN C1%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(Vnom || '' || Vapen);
END LOOP;
CLOSE C1;
END;
Si nos fijamos, en la declaración de los cursores explícitos no utilizamos la cláusula INTO, que sí se utilizaba en los cursores implícitos.
Ademas podéis ver que después del FETCH hemos comprobado si nos devuelve valores con la linea del EXIT. Es algo importante ya que si no nos devuelve nada el LOOP se interrumpirá.
Atributos del cursor
Para conocer detalles de la situación del cursor tenemos 4 atributos:
- %FOUND: devuelve verdadero di el ultimo FETCH ha recuperado algún valor; en caso contrario devuelve falso; si el cursor no esta abierto nos devuelve error.
- %NOTFOUND: hace justamente lo contrario al anterior.
- %ROWCOUNT: nos devuelve el número de filas recuperadas hasta el momento.
- %ISOPEN: devuelve verdadero si el cursor esta abierto.
Veamos ahora un ejemplo de utilización de %ROWCOUNT:
DECLARE
CURSOR C1 IS SELECT nombre from futbolista WHERE Cod='e1';
Vnom VARCHAR2(15);
BEGIN
OPEN C1;
LOOP
FETCH C1 INTO Vnom;
EXIT WHEN C1%NOTFOUND;
DBMS_OUTPUT.PUT_LINE (C1%ROWCOUNT || Vnom);
END LOOP;
CLOSE C1;
END;
Variables de acoplamientos en el manejo de cursores
En el ejemplo siguiente podemos observar que en la cláusula WHERE se incluye una variable que se debería haber declarado previamente. Este tipo de variables reciben el nombre de variables de acoplamiento. El programa la sustituirá por su valor en el momento en que se abre el cursor, y se seleccionarán las filas según dicho valor. Aunque ese valor cambie durante la recuperación de los datos con FETCH, el conjunto de filas que contiene el cursor no variará.El ejemplo nos muestra los futbolistas de un equipo cualquiera.
CREATE OR REPLACE PROCEDURE ver_futbolistas_por_equipos(codeq VARCHAR2)
IS
Vequi VARCHAR2(3);
CURSOR C1 IS SELECT nombre from futbolista where codeq=Vequi;
Vnom VARCHAR(15);
BEGIN
vequi:=codeq;
OPEN C1;
FETCH C1 INTO vnom;
WHILE C1%FOUND LOOP
DBMS_OUTPUT.PUT_LINE(Vnom);
FETCH C1 INTO Vnom;
END LOOP;
CLOSE C1;
END;