Una excepción es un error que interrumpe el flujo normal de las instrucciones del programa. PL/SQL nos proporciona el bloque de excepción que genera la excepción, lo que ayuda al programador a encontrar la falla y resolverla.
Hay dos tipos de excepciones definidas en PL/SQL
- Excepción definida por el usuario.
- Excepciones definidas por el sistema.
Sintaxis para escribir una excepción
WHEN exception THEN statement;
Sección de declaraciones DECLARE ;
BEGIN
comando(s) ejecutable(s);EXCEPCIÓN
CUANDO excepción1 ENTONCES
instrucción1;
CUANDO excepción2 ENTONCES
instrucción2;
[CUANDO otros ENTONCES]
/* código de manejo de excepciones predeterminado */FINAL;
Nota:
Cuando otra palabra clave debe usarse solo al final del bloque de manejo de excepciones, ya que no se ejecutará ninguna parte de manejo de excepciones presente más adelante, ya que el control saldrá del bloque después de ejecutar CUANDO OTROS.
- Excepciones definidas por el sistema:
- Excepciones del sistema con nombre.
- Excepciones del sistema sin nombre.
Estas excepciones están predefinidas en PL/SQL y se generan CUANDO se viola cierta regla de la base de datos.
Las excepciones definidas por el sistema se dividen en dos categorías:
- Excepciones del sistema con nombre: tienen un nombre predefinido por el sistema como ACCESS_INTO_NULL, DUP_VAL_ON_INDEX, LOGIN_DENIED, etc. La lista es bastante grande.
Así que discutiremos algunas de las excepciones más utilizadas:
Vamos a crear una mesa frikis.
create table geeks(g_id int , g_name varchar(20), marks int); insert into geeks values(1, 'Suraj',100); insert into geeks values(2, 'Praveen',97); insert into geeks values(3, 'Jessie', 99);
- NO_DATA_FOUND : se genera CUANDO una declaración SELECT INTO no devuelve filas. Por ejemplo:
DECLARE
temp
varchar
(20);
BEGIN
SELECT
g_id
into
temp
from
geeks
where
g_name=
'GeeksforGeeks'
;
exception
WHEN
no_data_found
THEN
dbms_output.put_line(
'ERROR'
);
dbms_output.put_line(
'there is no name as'
);
dbms_output.put_line(
'GeeksforGeeks in geeks table'
);
end
;
Producción:
ERROR there is no name as GeeksforGeeks in geeks table
- TOO_MANY_ROWS : se genera CUANDO una declaración SELECT INTO devuelve más de una fila.
DECLARE
temp
varchar
(20);
BEGIN
-- raises an exception as SELECT
-- into trying to return too many rows
SELECT
g_name
into
temp
from
geeks;
dbms_output.put_line(
temp
);
EXCEPTION
WHEN
too_many_rows
THEN
dbms_output.put_line(
'error trying to SELECT too many rows'
);
end
;
Producción:
error trying to SELECT too many rows
- VALUE_ERROR : este error se genera CUANDO se ejecuta una declaración que resultó en un error aritmético, numérico, de string, de conversión o de restricción. Este error se debe principalmente a un error del programador o a una entrada de datos no válida.
DECLARE
temp
number;
BEGIN
SELECT
g_name
into
temp
from
geeks
where
g_name=
'Suraj'
;
dbms_output.put_line(
'the g_name is '
||
temp
);
EXCEPTION
WHEN
value_error
THEN
dbms_output.put_line(
'Error'
);
dbms_output.put_line(
'Change data type of temp to varchar(20)'
);
END
;
Producción:
Error Change data type of temp to varchar(20)
- ZERO_DIVIDE = genera una excepción AL dividir con cero.
DECLARE
a
int
:=10;
b
int
:=0;
answer
int
;
BEGIN
answer:=a/b;
dbms_output.put_line(
'the result after division is'
||answer);
exception
WHEN
zero_divide
THEN
dbms_output.put_line(
'dividing by zero please check the values again'
);
dbms_output.put_line(
'the value of a is '
||a);
dbms_output.put_line(
'the value of b is '
||b);
END
;
Producción:
dividing by zero please check the values again the value of a is 10 the value of b is 0
- NO_DATA_FOUND : se genera CUANDO una declaración SELECT INTO no devuelve filas. Por ejemplo:
- Excepciones del sistema sin nombre: Oracle no proporciona el nombre de algunas excepciones del sistema llamadas excepciones del sistema sin nombre. Estas excepciones no ocurren con frecuencia. Estas excepciones tienen un código de dos partes y un mensaje asociado .
La forma de manejar estas excepciones es asignarles un nombre usando la sintaxis Pragma EXCEPTION_INIT :PRAGMA EXCEPTION_INIT(exception_name, -error_number);
error_number están predefinidos y tienen un rango de enteros negativos de -20000 a -20999.
Ejemplo:
DECLARE
exp exception;
pragma exception_init (exp, -20015);
n
int
:=10;
BEGIN
FOR
i
IN
1..n LOOP
dbms_output.put_line(i*i);
IF i*i=36
THEN
RAISE exp;
END
IF;
END
LOOP;
EXCEPTION
WHEN
exp
THEN
dbms_output.put_line(
'Welcome to GeeksforGeeks'
);
END
;
Producción:
1 4 9 16 25 36 Welcome to GeeksforGeeks
este tipo de usuarios puede crear sus propias excepciones de acuerdo con la necesidad y para generar estas excepciones se utiliza explícitamente el comando de generación.
Ejemplo:
- Divide el entero no negativo x por y de modo que el resultado sea mayor o igual a 1.
De la pregunta dada podemos concluir que existen dos excepciones
- La división sea cero.
- Si el resultado es mayor o igual a 1 significa que y es menor o igual a x.
DECLARE
x
int
:=&x; /*taking value
at
run
time
*/
y
int
:=&y;
div_r
float
;
exp1 EXCEPTION;
exp2 EXCEPTION;
BEGIN
IF y=0
then
raise exp1;
ELSEIF y > x
then
raise exp2;
ELSE
div_r:= x / y;
dbms_output.put_line(
'the result is '
||div_r);
END
IF;
EXCEPTION
WHEN
exp1
THEN
dbms_output.put_line(
'Error'
);
dbms_output.put_line(
'division by zero not allowed'
);
WHEN
exp2
THEN
dbms_output.put_line(
'Error'
);
dbms_output.put_line(
'y is greater than x please check the input'
);
END
;
Input 1: x = 20 y = 10 Output: the result is 2
Input 2: x = 20 y = 0 Output: Error division by zero not allowed
Input 3: x=20 y = 30 Output:<.em> Error y is greater than x please check the input
RAISE_APPLICATION_ERROR :
se utiliza para mostrar mensajes de error definidos por el usuario con un número de error cuyo rango está entre -20000 y -20999. Cuando se ejecuta RAISE_APPLICATION_ERROR, devuelve un mensaje de error y un código de error que tiene el mismo aspecto que el error integrado de Oracle.
Ejemplo:
DECLARE myex EXCEPTION; n NUMBER :=10; BEGIN FOR i IN 1..n LOOP dbms_output.put_line(i*i); IF i*i=36 THEN RAISE myex; END IF; END LOOP; EXCEPTION WHEN myex THEN RAISE_APPLICATION_ERROR(-20015, 'Welcome to GeeksForGeeks' ); END ; |
Producción:
Error report: ORA-20015: Welcome to GeeksForGeeks ORA-06512: at line 13 1 4 9 16 25 36
Nota: La salida se basa en el desarrollador de Oracle Sql, el orden de salida puede cambiar SI está ejecutando este código en otro lugar.
Reglas de alcance en el manejo de excepciones :
- No podemos DECLARAR una excepción dos veces, pero podemos DECLARAR la misma excepción en dos bloques diferentes.
- Las excepciones DECLARADAS dentro de un bloque son locales para ese bloque y globales para todos sus sub-bloques.
Como un bloque solo puede hacer referencia a excepciones locales o globales, los bloques que lo encierran no pueden hacer referencia a excepciones DECLARADAS en un subbloque.
Si volvemos a DECLARAR una excepción global en un subbloque, la declaración local prevalece, es decir, el alcance de local es mayor.
Ejemplo:
DECLARE GeeksforGeeks EXCEPTION; age NUMBER:=16; BEGIN -- sub-block BEGINs DECLARE -- this declaration prevails GeeksforGeeks EXCEPTION; age NUMBER:=22; BEGIN IF age > 16 THEN RAISE GeeksforGeeks; /* this is not handled*/ END IF; END ; -- sub-block ends EXCEPTION -- Does not handle raised exception WHEN GeeksforGeeks THEN DBMS_OUTPUT.PUT_LINE ( 'Handling GeeksforGeeks exception.' ); WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE ( 'Could not recognize exception GeeksforGeeks in this scope.' ); END ; |
Producción:
Could not recognize exception GeeksforGeeks in this scope.
ventajas:
- El manejo de excepciones es muy útil para el manejo de errores, sin él tenemos que emitir el comando en cada punto para verificar los errores de ejecución:
Ejemplo:Select .. .. check for 'no data found' error Select .. .. check for 'no data found' error Select .. .. check for 'no data found' error
Aquí podemos ver que no es robusto ya que el procesamiento de errores no está separado del procesamiento normal y SI nos perdemos alguna línea en el código, puede conducir a algún otro tipo de error.
- Con el manejo de excepciones, manejamos errores sin escribir declaraciones varias veces e incluso podemos manejar diferentes tipos de errores en un bloque de excepción:
Ejemplo:BEGIN SELECT ... SELECT ... SELECT ... . . . exception WHEN NO_DATA_FOUND THEN /* catches all 'no data found' errors */ ... WHEN ZERO_DIVIDE THEN /* different types of */ WHEN value_error THEN /* errors handled in same block */ ...
Del código anterior podemos concluir que el manejo de excepciones
- Mejora la legibilidad al permitirnos aislar las rutinas de manejo de errores y, por lo tanto, brindar robustez.
- Brinda confiabilidad , en lugar de verificar diferentes tipos de errores en cada punto, simplemente podemos escribirlos en un bloque de excepción y SI existe un error, se generará una excepción, lo que ayudará al programador a descubrir el tipo de error y eventualmente resolverlo.
Usos : uno de los usos reales de excepción se puede encontrar en el sistema de reserva de trenes en línea.
Al completar el código de la estación para reservar el boleto, SI ingresamos un código incorrecto, nos muestra la excepción de que el código no existe en la base de datos.
Referencia: Puede encontrar la lista de todas las excepciones predefinidas aquí.
Número total de excepciones predefinidas