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:
- Declaración (
DECLARE
): Se define el cursor y se asocia con una sentenciaSELECT
. - Apertura (
OPEN
): Se ejecuta la sentenciaSELECT
asociada 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
: DevuelveTRUE
si el últimoFETCH
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ú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
: DevuelveTRUE
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ónUNIQUE
.NO_DATA_FOUND
: Se dispara cuando una sentenciaSELECT INTO
no devuelve ninguna fila.TOO_MANY_ROWS
: Se dispara cuando una sentenciaSELECT 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;