Varios Casos ejemplo para el tratamiento de Excepciones:

Transcripción

Varios Casos ejemplo para el tratamiento de Excepciones:
Ejemplificación de los Casos ejemplo para el tratamiento de
Excepciones:
Caso 1
Caso 2
DECLARE
a EXCEPTION;
BEGIN
DBMS_OUTPUT.PUT_LINE('Inicio');
BEGIN
RAISE a;
DBMS_OUTPUT.PUT_LINE('Luego de raise a');
EXCEPTION
WHEN a THEN
DBMS_OUTPUT.PUT_LINE('a Se trata aquí');
END;
DBMS_OUTPUT.PUT_LINE('El control va aquí');
END;
/
DECLARE
a EXCEPTION;
b EXCEPTION;
BEGIN
DBMS_OUTPUT.PUT_LINE('Inicio');
BEGIN
RAISE b;
EXCEPTION
WHEN a THEN
DBMS_OUTPUT.PUT_LINE('Se trata a');
END;
DBMS_OUTPUT.PUT_LINE('Luego del subbloque');
EXCEPTION
WHEN b THEN
DBMS_OUTPUT.PUT_LINE('Se trata b aquí');
END;
/
Caso 3
Caso 4
DECLARE
a EXCEPTION; b EXCEPTION; c EXCEPTION;
BEGIN
DBMS_OUTPUT.PUT_LINE('Inicio');
BEGIN
RAISE c;
EXCEPTION
WHEN a THEN
DBMS_OUTPUT.PUT_LINE('Se trata a');
END;
DBMS_OUTPUT.PUT_LINE('Luego del subbloque');
EXCEPTION
WHEN b THEN
DBMS_OUTPUT.PUT_LINE('Se trata b');
END;
/
DECLARE
val NUMBER(5):='hola';
BEGIN
DBMS_OUTPUT.PUT_LINE('Inicio');
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('No capturó errores en
la declaración');
END;
/
Caso 5
Caso 6
BEGIN
DBMS_OUTPUT.PUT_LINE('Inicio');
DECLARE
x NUMBER(5):='Hola';
BEGIN
DBMS_OUTPUT.PUT_LINE('Soy el
subbloque');
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('No capturó
errores en la declaración');
END;
DBMS_OUTPUT.PUT_LINE('Luego del subbloque');
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('Se trata aquí');
END;
/
DECLARE
a EXCEPTION;
b EXCEPTION;
BEGIN
DBMS_OUTPUT.PUT_LINE('Inicio');
RAISE a;
EXCEPTION
WHEN a THEN
DBMS_OUTPUT.PUT_LINE('Estoy en a');
RAISE b;
WHEN b THEN
-- No captura a b
DBMS_OUTPUT.PUT_LINE('Estoy en b');
END;
/
Caso 7
Caso 8
DECLARE
a EXCEPTION; b EXCEPTION;
BEGIN
DBMS_OUTPUT.PUT_LINE('Inicio');
BEGIN
RAISE a;
EXCEPTION
WHEN a THEN
DBMS_OUTPUT.PUT_LINE('Estoy en a');
RAISE b;
WHEN b THEN
DBMS_OUTPUT.PUT_LINE('Estoy en b
subbloque');
END;
EXCEPTION
WHEN b THEN
DBMS_OUTPUT.PUT_LINE('Estoy en b externo');
END;
/
DECLARE
a EXCEPTION;
BEGIN
DBMS_OUTPUT.PUT_LINE('Inicio');
RAISE a;
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('Por causa de a');
END;
/
Otros casos:
a. Se declara una excepción con el mismo nombre en un bloque externo e
interno. Se dispara en el interno y no se trata en el interno pero si en el externo.
¿Qué sucede?
DECLARE
w EXCEPTION;
BEGIN
DECLARE
w EXCEPTION;
BEGIN
RAISE w;
END;
EXCEPTION
WHEN w THEN
DBMS_OUTPUT.PUT_LINE('Se generó w');
END;
/
Solución:
Estas dos w's son excepciones diferentes y por lo tanto el bloque externo no la captura
(de hecho la w interna NO es visible para el bloque externo).
Lo siguiente tampoco funciona:
BEGIN
DECLARE
w EXCEPTION;
BEGIN
RAISE w;
EXCEPTION
WHEN NO_DATA_FOUND THEN
NULL; --Instrucción nula
END;
EXCEPTION
WHEN w THEN
DBMS_OUTPUT.PUT_LINE('Se generó w');
END;
/
w NO es conocida por el bloque externo como era de esperarse.
b. Lo que si es válido es disparar desde el bloque interno una excepción externa incluso
si se llama igual que una interna (recuérdese que se debe “nombrar” el bloque):
<<externo>> --nombre del bloque
DECLARE
w EXCEPTION;
BEGIN
DECLARE
w EXCEPTION;
BEGIN
RAISE externo.w;
END;
EXCEPTION
WHEN w THEN
DBMS_OUTPUT.PUT_LINE('Se generó w externa desde el bloque interno');
END;
/
c. Sin embargo si en un bloque interno se genera una excepción predefinida ésta si es
capturada por el bloque externo (porque estas excepciones se pueden considerar como
globales)
BEGIN
DECLARE
a NUMBER;
BEGIN
a:= 7/0; --División por cero
END;
EXCEPTION
WHEN ZERO_DIVIDE THEN
DBMS_OUTPUT.PUT_LINE('Se dividió por cero');
END;
/
d. Sobre si desde la zona de excepción se puede "devolver" el control al bloque que
disparó la excepción:
DECLARE
a EXCEPTION;
BEGIN
RAISE a;
<<volver>>
DBMS_OUTPUT.PUT_LINE('¡Ha retornado!');
EXCEPTION
WHEN a THEN
GOTO volver;
END;
/
No es válido.
Pero lo siguiente si es válido:
DECLARE
a EXCEPTION;
BEGIN
FOR k IN 1..10 LOOP
DECLARE
a EXCEPTION;
BEGIN
RAISE a;
EXCEPTION
WHEN a THEN
DBMS_OUTPUT.PUT_LINE('Veces que se ha disparado a: '|| k);
END;
END LOOP;
--El ciclo vuelve y "sube" y se ejecuta de nuevo el
--subbloque...
END;
/
Lo siguiente también es correcto:
DECLARE
dividendo NUMBER(3):= 4;
divisor NUMBER(3);
resultado NUMBER(3);
BEGIN
--A raiz de alguna operación se asigna un valor al divisor
--en este caso para ejemplificar se asigna un cero
divisor:= 0;
<<volver>>
BEGIN
resultado := dividendo/divisor;
DBMS_OUTPUT.PUT_LINE('La división fue '||resultado);
EXCEPTION
WHEN zero_divide THEN
DBMS_OUTPUT.PUT_LINE('el divisor era cero, ¡se corregirá!');
divisor:= 2;
GOTO volver;
END;
END;
/

Documentos relacionados