Gestion des exceptions
Cette section optionnelle est introduite par le mot clé EXCEPTION, elle contient les instructions à exécuter lors des éventuelles générées par la section d’exécution.
Il existe 2 familles d’exception:
- Declenchées implicitement:
Exceptions Oracle predenies
Exceptions Oracle Non-predenies - Declencheés explicitement:
Exceptions denies par l’utilisateur
Lorsqu’une erreur survient dans la section ‘exécution’ elle déclenche une exception et le programme est ‘débranché’ vers la section ‘exception’. Chaque erreur a un code numérique spécifique répertorié par Oracle (voir la doc officielle des erreurs Oracle pour plus d’infos) ou fixé par le développeur.
EXCEPTION
WHEN e x c e p t i o n 1 [OR e x c e p t i o n 2 . . . ] THEN
enonce1 ;
enonce2 ;
. . .
[WHEN e x c e p t i o n 2 [OR e x c e p t i o n 4 . . . ] THEN
enonce3 ;
enonce4 ;
. . . ]
[WHEN OTHERS THEN
enonce5 ;
enonce6 ;
. . . ]
Voyons un exemple d’erreur sans gestion d’exception particulière:
SQL> Declare
2 Nom EMPLOYEES.last_name%Type;
3 Begin
4 DBMS_OUTPUT.PUT_LINE('Select');
5 Select last_name Into nom From EMPLOYEES
6 Where employee_id=1111;
7 DBMS_OUTPUT.PUT_LINE('Update');
8 update EMPLOYEES SET SALARY=SALARY*1.1;
9
10 end;
11 .
SQL> /
Select
Declare
*
ERROR at line 1:
ORA-01403: no data found
ORA-06512: at line 5
La requête 1 ne ramène aucune ligne, c’est une erreur courante, correspondant en fait à l’exception prédéfinie NO_DATA_FOUND. Le message d’erreur par défaut (en anglais dans notre config) est renvoyé, et la suite du programme (update) court-circuitée.
Ajoutons maintenant un traitement spécifique de cette exception utilisant son nom prédéfini:
SQL> Declare
2 Nom EMPLOYEES.last_name%Type;
3 Begin
4 DBMS_OUTPUT.PUT_LINE(‘Select’);
5 Select last_name Into nom From EMPLOYEES
6 Where employee_id=1111;
7 DBMS_OUTPUT.PUT_LINE(‘Update’);
8 update EMPLOYEES SET SALARY=SALARY*1.1;
9
10 exception WHEN NO_DATA_FOUND
11 THEN DBMS_OUTPUT.PUT_LINE(‘Désolé, pas de résultat’);
12
13 end;
14 .
SQL> /
Select
Désolé, pas de résultatPL/SQL procedure successfully completed.
On n’a plus désormais le message d’erreur ‘systeme’ mais un message plus intelligible par l’utilisateur.
Parmi pléthore d’erreurs Oracle il existe un nombre limité de cas prédéfinis, en Voici la liste:
| NOM Exception | Erreur Oracle | CODE ERREUR (SQLCODE) |
|---|---|---|
| ACCESS_INTO_NULL | ORA-06530 | -6530 |
| CASE_NOT_FOUND | ORA-06592 | -6592 |
| COLLECTION_IS_NULL | ORA-06531 | -6531 |
| CURSOR_ALREADY_OPEN | ORA-06511 | -6511 |
| DUP_VAL_ON_INDEX | ORA-00001 | -1 |
| INVALID_CURSOR | ORA-01001 | -1001 |
| INVALID_NUMBER | ORA-01722 | -1722 |
| LOGIN_DENIED | ORA-01017 | -1017 |
| NO_DATA_FOUND | ORA-01403 | +100 |
| NOT_LOGGED_ON | ORA-01012 | -1012 |
| PROGRAM_ERROR | ORA-06501 | -6501 |
| ROWTYPE_MISMATCH | ORA-06504 | -6504 |
| SELF_IS_NULL | ORA-30625 | -30625 |
| STORAGE_ERROR | ORA-06500 | -6500 |
| SUBSCRIPT_BEYOND_COUNT | ORA-06533 | -6533 |
| SUBSCRIPT_OUTSIDE_LIMIT | ORA-06532 | -6532 |
| SYS_INVALID_ROWID | ORA-01410 | -1410 |
| TIMEOUT_ON_RESOURCE | ORA-00051 | -51 |
| TOO_MANY_ROWS | ORA-01422 | -1422 |
| VALUE_ERROR | ORA-06502 | -6502 |
| ZERO_DIVIDE | ORA-01476 | -1476 |
Les autres exceptions doivent être gérées via leur code d’erreur SQLCODE. Associé à ce SQLCODE on peut également récuperer le message/texte d’erreur standard renvoyé par Oracle: SQLERRM
Exception générique
On affiche simplement le code d’erreur:
SQL> Declare
2 Nom EMPLOYEES.last_name%Type;
3 Begin
4 DBMS_OUTPUT.PUT_LINE(‘Insert’);
5 INSERT INTO employees(LAST_NAME) VALUES(‘DD’);
6 DBMS_OUTPUT.PUT_LINE(‘Insert OK’);
7 exception
8 WHEN OTHERS
9 THEN DBMS_OUTPUT.PUT_LINE(‘Il y a eu une erreur no:’||SQLCODE);
10 end;
11 .
SQL> /
Insert
Il y a eu une erreur no:-1400
Exception personnalisée
On peut associer un code erreur Oracle à ses propres variables exception à l’aide du mot clé PRAGMA EXCEPTION_INIT, dans la section déclarative de la façon suivante :
Nom_exception EXCEPTION ;
PRAGMA EXCEPTION_INIT(nom_exception, -code_error_oracle);
Voyons ce que donne une violation de contrainte (insertion d’un doublon sur clé primaire par exemple):
SQL> insert into employees select * from employees;
Erreur SQL : ORA-00001: unique constraint (HR.EMP_EMAIL_UK) violated
On voit que l’erreur ORA-00001 est générée (SQLCODE 1 donc). Prenons en charge cette exception avec une contrainte personnalisée:
DECLARE
cdoub EXCEPTION;
PRAGMA EXCEPTION_INIT( cdoub, -1);
BEGIN
insert into employees select * from employees;
EXCEPTION
WHEN cdoub THEN
DBMS_OUTPUT.PUT_LINE ( ‘tentative d insertion de doublon’ ) ;
END;
on obtient:
Procédure PL/SQL terminée.
tentative d insertion de doublon


