plsql
Gestion des exceptions
Recherche…
Introduction
Oracle produit diverses exceptions. Vous serez peut-être surpris de voir à quel point il peut être fastidieux d’arrêter votre code avec un message peu clair. Pour améliorer la capacité de votre code PL / SQL à être corrigé facilement, il est nécessaire de gérer les exceptions au niveau le plus bas. Ne cachez jamais une exception "sous le tapis", sauf si vous êtes ici pour garder votre morceau de code uniquement pour vous et pour que personne d'autre ne le maintienne.
Les erreurs prédéfinies .
Gestion des exceptions d'erreur de connexion
Chaque erreur Oracle standard est associée à un numéro d'erreur. Il est important d'anticiper ce qui pourrait mal tourner dans votre code. Ici, pour une connexion à une autre base de données, il peut être:
-
-28000
compte est verrouillé -
-28001
mot de passe expiré -
-28002
période de grâce -
-1017
mauvais utilisateur / mot de passe
Voici un moyen de tester ce qui ne va pas avec l'utilisateur utilisé par le lien de la base de données:
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;
/
Définir une exception personnalisée, l'élever et voir d'où elle provient
Pour illustrer cela, voici une fonction qui a 3 comportements différents "erronés"
- le paramètre est complètement stupide: nous utilisons une expression définie par l'utilisateur
- paramètre a une faute de frappe: nous utilisons l'erreur standard
NO_DATA_FOUND
Oracle - une autre affaire, mais pas traitée
N'hésitez pas à l'adapter à vos normes:
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;
/
Donner sur une base de données régulière:
[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
Rappelez-vous que cette exception concerne les cas rares . J'ai vu des applications qui ont soulevé une exception à chaque accès, simplement pour demander un mot de passe utilisateur, en disant "non connecté" ... tant de déchets de calcul.