Programación PL/SQL: Cursores y Gestión de Excepciones

Clasificado en Informática

Escrito el en español con un tamaño de 6,66 KB

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:

  1. Declaración (DECLARE): Se define el cursor y se asocia con una sentencia SELECT.
  2. Apertura (OPEN): Se ejecuta la sentencia SELECT asociada al cursor y se cargan los resultados en el área de contexto.
  3. Recuperación (FETCH): Se recuperan las filas una a una del cursor.
  4. 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: Devuelve TRUE si el último FETCH ha 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ún FETCH, devuelve NULL.
  • %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: Devuelve TRUE si 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ón UNIQUE.
  • NO_DATA_FOUND: Se dispara cuando una sentencia SELECT INTO no devuelve ninguna fila.
  • TOO_MANY_ROWS: Se dispara cuando una sentencia SELECT INTO devuelve 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;

Entradas relacionadas: