Oracle

Excepciones en los cursores PL/SQL

Por : Jhons_1101
2019-02-01
Tags :
Como vimos en la lección anterior, los errores se puden manipular. Para este caso veremos el correcto manejo de errores en los cursores, ayudando a controlar y segmentar el origen del error y dismunuir el impacto visual que refleja un error de sistema.

Existen errores que son propios del sistema y errores que podremos crear para darle manejo a la lógica de negocio de nuestra aplicación. En los dos casos, el resultado será un mensaje de error que nos proporciona información del motivo por el cual ocurre el error, y un número que lo identifica.
compartir en facebook compartir en Google compartir en Twitter compartir en Blogger compartir como código embebido compartir la url
Existen dos maneras para usar las excepciones en los cursosres, ya sean las definidas por el sistema (internas) o las definidas por el usuario. Veamos un par de ejemplos de cada una de ellas.


-- Excepción interna (del sistema)
DECLARE
    lrt_estudiante tbl_estudiantes%ROWTYPE;
BEGIN

    BEGIN
        SELECT *  INTO lrt_estudiante
        FROM tbl_estudiantes WHERE cod_estudiante = 1000;
    EXCEPTION
        WHEN NO_DATA_FOUND THEN
            DBMS_OUTPUT.PUT_LINE('Error, el estudiante no existe');
        WHEN TOO_MANY_ROWS THEN
            DBMS_OUTPUT.PUT_LINE('Error, existe más de un estudiante');
        WHEN OTHERS THEN
            DBMS_OUTPUT.PUT_LINE('Error, abortando la ejecución.');
    END;
END;




-----------------------------------------------------------------------
-- Excepción definida por el usuario
-----------------------------------------------------------------------
BEGIN
	-- declaración...
EXCEPTION
WHEN OTHERS THEN
	RAISE_APPLICATION_ERROR(-20000, 'mensaje'); -- los códigos de error van desde (-20000 al 200099)
	EXIT;
END;


-- El RAISE_APPLICATION_ERROR Se utiliza en dos lugares distintos:
-- * SECCIÓN EJECUTABLE
-- * SECCIÓN DE EXCEPCIONES

-- * SECCIÓN EJECUTABLE
BEGIN
    IF cursor%NOTFOUND THEN
        RAISE_APPLICATION_ERROR(-20000, 'mensaje');
    END IF;
END;

-- * SECCIÓN DE EXCEPCIONES
EXCEPTION 
    WHEN NO_DATA_FOUND THEN
        RAISE_APPLICATION_ERROR(-20000, 'mensaje');
END;

Un ejemplo más complejo en donde se pueden mezclar el manejo de las excepciones en los cursores, Ya sea combinando entre excepciones sólo internas del sistema, sólo predefinidas por el usuario, o la combinación de ambas, puede ser este un ejemplo de ello..



-----------------------------------------------------------------------
-- Excepciones sólo internas del sistema
-----------------------------------------------------------------------
DECLARE
    lrt_estudiante tbl_estudiantes%ROWTYPE;
BEGIN

    BEGIN
        SELECT *  INTO lrt_estudiante
        FROM tbl_estudiantes WHERE cod_estudiante = 1000;
    EXCEPTION
        WHEN NO_DATA_FOUND THEN
            DBMS_OUTPUT.PUT_LINE('Error, el estudiante no existe');
        WHEN TOO_MANY_ROWS THEN
            DBMS_OUTPUT.PUT_LINE('Error, existe más de un estudiante');
        WHEN OTHERS THEN
            DBMS_OUTPUT.PUT_LINE('Error, abortando la ejecución.');
    END;
END;


-----------------------------------------------------------------------
-- Excepciones sólo predefinidas por el usuario
-----------------------------------------------------------------------
DECLARE
    lrc_estudiante tbl_estudiantes%ROWTYPE;
BEGIN   

    SELECT * 
    INTO lrc_estudiante
    FROM tbl_estudiantes
    WHERE cod_estudiante = 100;
    
   DBMS_OUTPUT.PUT_LINE(lrc_estudiante.FEC_NACIMIENTO);
    IF lrc_estudiante.FEC_NACIMIENTO > TRUNC(SYSDATE)  THEN
        RAISE_APPLICATION_ERROR(-20000, 'Error, la fecha de nacimiento del estudiante no puede ser mayor a la fecha actual del sistema');
    END IF;
END;


-----------------------------------------------------------------------
-- La combinación de ambas excepciones
-----------------------------------------------------------------------
DECLARE
    lrt_estudiante tbl_estudiantes%ROWTYPE;
BEGIN

    BEGIN
        SELECT *  INTO lrt_estudiante
        FROM tbl_estudiantes     WHERE cod_estudiante = 100;
        
        IF lrt_estudiante.FEC_NACIMIENTO > TRUNC(SYSDATE)  THEN
            RAISE_APPLICATION_ERROR(-20000, 'Error, la fecha de nacimiento del estudiante no puede ser mayor a la fecha actual del sistema');
        END IF;
    EXCEPTION
        WHEN NO_DATA_FOUND THEN
            DBMS_OUTPUT.PUT_LINE('Error, el estudiante no existe');
        WHEN TOO_MANY_ROWS THEN
            DBMS_OUTPUT.PUT_LINE('Error, existe más de un estudiante');
        WHEN OTHERS THEN
            DBMS_OUTPUT.PUT_LINE('Error, abortando la ejecución.');
    END;
END;



Existe una prioridad para el manejo de excepciones en PL/SQL Oracle, las exepciones serán aplicadas según la siguiente prioridad.

1. Si se define una excepción en el cuerpo de la ejecución justo despues de evaluar una condicion o ejecución.
La excepción tomará prioridad alta y entrará a esta, buscando si cuenta con un RAISE para disparlo inmediatamente y despues de ello continuará con el 'WHEN OTHERS'.. en tal caso de que no esté definido.... buscará su declaración en el final del bloque, procedimiento o paquete y terminará ejecutando lo que su declaración defina, ver imagen 1..

2. Si no está definida la excepción en el cuerpo de la ejecución justo despues de evaluar una condicion o ejecución.. la prioridad cambia a prioridad media y se ejecuta lo declarado al final del bloque, ver imagen 2..

3. Si no está definida la excepción, ni en el cuerpo justo despues de evaluar una condicion o ejecución, ni al final del bloque, se dispara la excepción por defecto 'WHEN OTHERS' y esta ejecutará lo que esté declarado.
En tal caso de que no esté declarada la excepción 'WHEN OTHERS' y se genere un error... se produce un error de compilación.


DECLARE
   lnu_codEstudiante   tbl_estudiantes%ROWTYPE;
BEGIN
    BEGIN
        SELECT * INTO lnu_codEstudiante
        FROM tbl_estudiantes
        WHERE cod_estudiante = 1000;
    EXCEPTION
        WHEN NO_DATA_FOUND
        THEN
            -- En este caso, busca si existe un RAISE_APPLICATION_ERROR, como existe,
            -- lo ejecuta y termina la ejecución del bloque.
            DBMS_OUTPUT.PUT_LINE('Error, el estudiante no existe RAISE.');
            RAISE_APPLICATION_ERROR (-20000, 'Error, el estudiante no existe RAISE.');
    END;
EXCEPTION
    WHEN NO_DATA_FOUND
        THEN
            -- Aquí hubiese entrado si arriba en el 'NO_DATA_FOUND'
            -- no hubiese un RAISE_APPLICATION_ERROR.
            DBMS_OUTPUT.PUT_LINE ('Error, el estudiante no existe DBMS.');
    WHEN TOO_MANY_ROWS
        THEN
            DBMS_OUTPUT.PUT_LINE ('Error, existe más de un estudiante DBMS.');
    WHEN OTHERS
        THEN
            DBMS_OUTPUT.PUT_LINE ('Error, abortando ejecución DBMS.');
            RAISE;
END;


Puedes probar este bloque de código comentando el 'RAISE_APPLICATION_ERROR (-20000, 'Error, el estudiante no existe RAISE.');', entonces así, mostrará en la consola del DBMS_OUTPUT lo siguiente: 'DBMS_OUTPUT.PUT_LINE ('Error, existe más de un estudiante DBMS.');'.

Si por el contrario, cambiamos la consulta y esta nos arroja más de un resultado, entonces se produce la excepción 'TOO_MANY_ROWS'... y como esta no está definida en el cuerpo del bloque, si no al final, entonces la prioridad cambia y se ejecuta lo siguiente: 'DBMS_OUTPUT.PUT_LINE ('Error, existe más de un estudiante DBMS.');'.

Imagen 1. Manejo de excepciones prioridad alta

Manejo de excepciones prioridad alta

Imagen 1. Manejo de excepciones prioridad media

Manejo de excepciones prioridad media






Si este contenido te fue útil, no olvides compartirlo en redes sociales, Considéralo. Puede ser la manera de agradecer!


Agrega tu comentario...

Puedes utilizar etiquetas <pre></pre>, <p></p>, <div></div>, + (Nombre usuario, para responderle a alguien)

xsjL8ho





Este post no tiene comentarios, sé el primero en hacerlo
Esta entrada no cuenta con imágenes adjuntas

Unete al grupo de whatsApp +57 316 392 6456

Sigue el grupo en facebook

Siguenos.....