plsql
Manejo de excepciones
Buscar..
Introducción
Oracle produce una variedad de excepciones. Es posible que se sorprenda de lo tedioso que puede ser que su código se detenga con un mensaje poco claro. Para mejorar la capacidad de su código PL / SQL para arreglarse fácilmente, es necesario manejar las excepciones en el nivel más bajo. Nunca oculte una excepción "debajo de la alfombra", a menos que esté aquí para guardar su parte del código solo para usted y para que nadie más lo pueda mantener.
Los errores predefinidos .
Manejo de excepciones de error de conexión
Cada error estándar de Oracle está asociado con un número de error. Es importante anticipar lo que podría salir mal en su código. Aquí para una conexión a otra base de datos puede ser:
-
-28000
cuenta está bloqueada -
-28001
contraseña caducada -
-28002
periodo de gracia -
-1017
usuario incorrecto / contraseña
Aquí hay una manera de probar qué falla con el usuario que usa el enlace de la base de datos:
declare
v_dummy number;
begin
-- testing db link
execute immediate 'select COUNT(1) from [email protected]' into v_dummy ;
-- if we get here, exception wasn't raised: display COUNT's result
dbms_output.put_line(v_dummy||' users on PASS db');
EXCEPTION
-- exception can be referred by their name in the predefined Oracle's list
When LOGIN_DENIED
then
dbms_output.put_line('ORA-1017 / USERNAME OR PASSWORD INVALID, TRY AGAIN');
When Others
then
-- or referred by their number: stored automatically in reserved variable SQLCODE
If SQLCODE = '-2019'
Then
dbms_output.put_line('ORA-2019 / Invalid db_link name');
Elsif SQLCODE = '-1035'
Then
dbms_output.put_line('ORA-1035 / DATABASE IS ON RESTRICTED SESSION, CONTACT YOUR DBA');
Elsif SQLCODE = '-28000'
Then
dbms_output.put_line('ORA-28000 / ACCOUNT IS LOCKED. CONTACT YOUR DBA');
Elsif SQLCODE = '-28001'
Then
dbms_output.put_line('ORA-28001 / PASSWORD EXPIRED. CONTACT YOUR DBA FOR CHANGE');
Elsif SQLCODE = '-28002'
Then
dbms_output.put_line('ORA-28002 / PASSWORD IS EXPIRED, CHANGED IT');
Else
-- and if it's not one of the exception you expected
dbms_output.put_line('Exception not specifically handled');
dbms_output.put_line('Oracle Said'||SQLCODE||':'||SQLERRM);
End if;
END;
/
Defina una excepción personalizada, levántela y vea de dónde viene.
Para ilustrar esto, aquí hay una función que tiene 3 comportamientos "incorrectos" diferentes
- el parámetro es completamente estúpido: usamos una expresión definida por el usuario
- el parámetro tiene un error tipográfico:
NO_DATA_FOUND
error estándarNO_DATA_FOUND
Oracle - otro caso, pero no manejado
Siéntete libre de adaptarlo a tus estándares:
DECLARE
this_is_not_acceptable EXCEPTION;
PRAGMA EXCEPTION_INIT(this_is_not_acceptable, -20077);
g_err varchar2 (200) := 'to-be-defined';
w_schema all_tables.OWNER%Type;
PROCEDURE get_schema( p_table in Varchar2, p_schema out Varchar2)
Is
w_err varchar2 (200) := 'to-be-defined';
BEGIN
w_err := 'get_schema-step-1:';
If (p_table = 'Delivery-Manager-Is-Silly') Then
raise this_is_not_acceptable;
end if;
w_err := 'get_schema-step-2:';
Select owner Into p_schema
From all_tables
where table_name like(p_table||'%');
EXCEPTION
WHEN NO_DATA_FOUND THEN
-- handle Oracle-defined exception
dbms_output.put_line('[WARN]'||w_err||'This can happen. Check the table name you entered.');
WHEN this_is_not_acceptable THEN
-- handle your custom error
dbms_output.put_line('[WARN]'||w_err||'Please don''t make fun of the delivery manager.');
When others then
dbms_output.put_line('[ERR]'||w_err||'unhandled exception:'||sqlerrm);
raise;
END Get_schema;
BEGIN
g_err := 'Global; first call:';
get_schema('Delivery-Manager-Is-Silly', w_schema);
g_err := 'Global; second call:';
get_schema('AAA', w_schema);
g_err := 'Global; third call:';
get_schema('', w_schema);
g_err := 'Global; 4th call:';
get_schema('Can''t reach this point due to previous error.', w_schema);
EXCEPTION
When others then
dbms_output.put_line('[ERR]'||g_err||'unhandled exception:'||sqlerrm);
-- you may raise this again to the caller if error log isn't enough.
-- raise;
END;
/
Dar en una base de datos regular:
[WARN]get_schema-step-1:Please don't make fun of the delivery manager.
[WARN]get_schema-step-2:This can happen. Check the table name you entered.
[ERR]get_schema-step-2:unhandled exception:ORA-01422: exact fetch returns more than requested number of rows
[ERR]Global; third call:unhandled exception:ORA-01422: exact fetch returns more than requested number of rows
Recuerde que la excepción está aquí para manejar casos raros . Vi aplicaciones que generaron una excepción en cada acceso, solo para solicitar una contraseña de usuario, diciendo "no conectado" ... tanto desperdicio de cómputo.