PL SQL – Gestion des exceptions

image_pdfimage_print

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 prede nies
    Exceptions Oracle Non-prede nies
  • Declencheés explicitement:
    Exceptions de nies 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ésultat

PL/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