Cursores explícitos y gestión de excepciones en PL/SQL
Resumen
El documento explica los cursores explícitos en PL/SQL, su ciclo de vida (declaración, apertura, recuperación y cierre), sus atributos y el uso de variables de acoplamiento y del bucle FOR...LOOP. También trata el manejo de excepciones, tanto las predefinidas por Oracle como las definidas por el usuario, con ejemplos de código.
Puntos clave
- Los cursores explícitos permiten trabajar con consultas que devuelven más de una fila.
- El ciclo de vida de un cursor explícito tiene cuatro fases: DECLARE, OPEN, FETCH y CLOSE.
- Los atributos %FOUND, %NOTFOUND, %ROWCOUNT e %ISOPEN permiten controlar el estado del cursor.
- El bucle FOR...LOOP simplifica el uso de cursores, ya que Oracle gestiona automáticamente la apertura, la recuperación y el cierre.
- Las excepciones predefinidas más comunes son DUP_VAL_ON_INDEX, NO_DATA_FOUND y TOO_MANY_ROWS.
- Las excepciones definidas por el usuario se declaran con EXCEPTION, se disparan con RAISE y se tratan en el bloque EXCEPTION.
Conceptos Fundamentales de Cursores en PL/SQL
Como los cursores implícitos solo pueden devolver una fila, para trabajar con conjuntos de resultados más grandes, se utilizan los cursores explícitos.
Cursores Explícitos: Definición y Ciclo de Vida
Los cursores explícitos se emplean para trabajar con consultas que devuelven más de una fila. Su ciclo de vida se compone de cuatro fases principales:
- Declaración (
DECLARE): Se define el cursor y se asocia con una sentenciaSELECT. - Apertura (
OPEN): Se ejecuta la sentenciaSELECTasociada al cursor y se cargan los resultados en el área de contexto. - Recuperación (
FETCH): Se recuperan las filas una a una del cursor. - Cierre (
CLOSE): Se libera el área de contexto del cursor.
Sintaxis Básica de un Cursor Explícito
DECLARE
CURSOR <NOMBRE_CURSOR> IS <SENTENCIA_SELECT>;
BEGIN
OPEN <NOMBRE_CURSOR>;
LOOP
FETCH <NOMBRE_CURSOR> INTO <NOMBRE_VARIABLE>;
EXIT WHEN <NOMBRE_CURSOR>%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(V_NOMBRE || '*' || V_LOCALIDAD);
END LOOP;
CLOSE <NOMBRE_CURSOR>;
END;Atributos de los Cursores Explícitos
Los cursores explícitos disponen de atributos que permiten verificar su estado y el resultado de las operaciones:
%FOUND: DevuelveTRUEsi el últimoFETCHha recuperado algún valor. Si el cursor no estaba abierto, devuelve un error; si estaba abierto pero no se había ejecutado aún ningúnFETCH, devuelveNULL.%NOTFOUND: Hace lo contrario al anterior. Se suele utilizar como condición de salida en bucles.%ROWCOUNT: Devuelve el número de filas recuperadas hasta el momento por el cursor.%ISOPEN: DevuelveTRUEsi el cursor está abierto.
Variables de Acoplamiento en el Manejo de Cursores
Se utilizan cuando la condición de una sentencia SELECT no es un dato específico, sino que se tiene que introducir dinámicamente, por ejemplo, a través de un parámetro de procedimiento.
Ejemplo de Cursor con Variable de Acoplamiento
CREATE OR REPLACE PROCEDURE VER_EMPLE_POR_DEPT (DEP VARCHAR2)
AS
V_DEPT NUMBER(2);
CURSOR C1 IS SELECT APELLIDO FROM EMPLE WHERE DEPT_NO = V_DEPT;
V_APELLIDO VARCHAR2(10);
BEGIN
V_DEPT := DEP;
OPEN C1;
FETCH C1 INTO V_APELLIDO;
WHILE C1%FOUND LOOP
DBMS_OUTPUT.PUT_LINE(V_APELLIDO);
FETCH C1 INTO V_APELLIDO;
END LOOP;
CLOSE C1;
END;El programa sustituirá la variable V_DEPT por su valor en el momento en que se abre el cursor, y se seleccionarán las filas según dicho valor.
Cursores FOR...LOOP: Simplificando la Iteración
El bucle FOR...LOOP simplifica las tareas de crear y gestionar un cursor al omitir la declaración explícita, la apertura, el FETCH y el cierre. Oracle gestiona automáticamente estas operaciones.
Ejemplo de Cursor FOR...LOOP
DECLARE
CURSOR MI_CURSOR IS SELECT APELLIDO, OFICIO, COMISION FROM EMPLE
WHERE COMISION > 500;
BEGIN
FOR V_REG IN MI_CURSOR LOOP
DBMS_OUTPUT.PUT_LINE(V_REG.APELLIDO || '*' ||
V_REG.OFICIO || '*' || TO_CHAR(V_REG.COMISION));
END LOOP;
END;Cursores con Parámetros
Los cursores pueden aceptar parámetros, lo que los hace más flexibles y reutilizables. Esto permite pasar valores a la sentencia SELECT del cursor en el momento de su apertura, sin necesidad de variables de acoplamiento explícitas.
(Nota del profesor: El documento original no incluye un ejemplo de código para cursores con parámetros. Se recomienda añadir uno para una comprensión completa.)
Uso de Cursores para Actualizar Filas
Los cursores también pueden utilizarse para actualizar o eliminar filas de forma controlada, especialmente cuando se necesita procesar cada fila individualmente antes de aplicar una modificación. Esto se logra a menudo con la cláusula FOR UPDATE en la declaración del cursor y WHERE CURRENT OF en las sentencias UPDATE o DELETE.
(Nota del profesor: El documento original no incluye un ejemplo de código para la actualización de filas con cursores. Se recomienda añadir uno para una comprensión completa.)
Manejo de Excepciones en PL/SQL
Las excepciones sirven para tratar errores en tiempo de ejecución, así como situaciones de error definidas por el usuario, permitiendo que el programa continúe su ejecución de forma controlada.
Estructura del Bloque EXCEPTION
EXCEPTION
WHEN <NOMBRE_DE_EXCEPCION1> THEN
<INSTRUCCIONES>;
WHEN <NOMBRE_DE_EXCEPCION2> THEN
<INSTRUCCIONES>;
[WHEN OTHERS THEN
<INSTRUCCIONES>;]
END <NOMBRE_DE_PROGRAMA>;Excepciones Internas Predefinidas
Estas excepciones están predefinidas por Oracle y se disparan automáticamente al producirse determinados errores comunes:
DUP_VAL_ON_INDEX: Se produce al intentar almacenar un valor que crearía duplicados en una columna con una restricciónUNIQUE.NO_DATA_FOUND: Se dispara cuando una sentenciaSELECT INTOno devuelve ninguna fila.TOO_MANY_ROWS: Se dispara cuando una sentenciaSELECT INTOdevuelve más de una fila.
Excepciones Definidas por el Usuario
Las excepciones definidas por el usuario se emplean para tratar condiciones de error específicas que son relevantes para la lógica de negocio del programador.
Ejemplo de Excepción Definida por el Usuario
DECLARE
IMPORTE_ERRONEO EXCEPTION;
PRECIO NUMBER := 10; -- Ejemplo de variable
PRECIO_MIN NUMBER := 15;
PRECIO_MAXIMO NUMBER := 100;
BEGIN
IF PRECIO NOT BETWEEN PRECIO_MIN AND PRECIO_MAXIMO THEN
RAISE IMPORTE_ERRONEO;
END IF;
-- Lógica de negocio si el precio es válido
DBMS_OUTPUT.PUT_LINE('Precio válido. Venta procesada.');
EXCEPTION
WHEN IMPORTE_ERRONEO THEN
DBMS_OUTPUT.PUT_LINE('IMPORTE ERRÓNEO. VENTA CANCELADA.');
END;Descargar
PDF Word HTMLPreguntas frecuentes
¿Para qué se usan los cursores explícitos en PL/SQL?
Se emplean cuando una consulta devuelve más de una fila, ya que los cursores implícitos solo pueden devolver una. Permiten recorrer el conjunto de resultados fila a fila.
¿Qué devuelve el atributo %NOTFOUND de un cursor?
Devuelve TRUE cuando el último FETCH no ha recuperado ninguna fila. Es el contrario de %FOUND y se suele usar como condición de salida en bucles.
¿Qué excepción se dispara si SELECT INTO no devuelve filas?
Se dispara la excepción NO_DATA_FOUND. Si devuelve más de una fila, se dispara TOO_MANY_ROWS.
Ponte a prueba
Tarjetas de repaso
Pulsa una tarjeta para ver la respuesta.
Test
Preguntas generadas con IA a partir del documento: comprueba las respuestas con el texto.