La gestion des exceptions en PL/SQL Oracle : guide complet

Gérer les exceptions en PL/SQL Oracle : exceptions prédéfinies, personnalisées, RAISE_APPLICATION_ERROR, EXCEPTION_INIT, SQLCODE/SQLERRM et bonnes pratiques.

Illustration : la gestion des exceptions PL/SQL

La gestion des exceptions en PL/SQL permet de capturer les erreurs d’exécution dans un bloc EXCEPTION au lieu de laisser le programme planter. Oracle propose des exceptions prédéfinies (NO_DATA_FOUND, DUP_VAL_ON_INDEX…), des exceptions personnalisées, et des outils pour relever ou tracer proprement les erreurs. Voici le guide complet avec exemples.

Publicité

La structure d’un bloc avec gestion d’erreurs

BEGIN
  -- code susceptible d'échouer
EXCEPTION
  WHEN nom_exception THEN
    -- traitement
  WHEN OTHERS THEN
    -- filet de sécurité
END;

Les exceptions prédéfinies les plus utiles

ExceptionErreur OracleQuand
NO_DATA_FOUNDORA-01403SELECT INTO ne ramène aucune ligne
TOO_MANY_ROWSORA-01422SELECT INTO ramène > 1 ligne
DUP_VAL_ON_INDEXORA-00001doublon sur contrainte unique
VALUE_ERRORORA-06502conversion / taille de variable
ZERO_DIVIDEORA-01476division par zéro
BEGIN
  SELECT email INTO v_email FROM clients WHERE id = p_id;
EXCEPTION
  WHEN NO_DATA_FOUND THEN
    v_email := NULL;  -- ou un traitement adapté
  WHEN TOO_MANY_ROWS THEN
    RAISE_APPLICATION_ERROR(-20010, 'Plusieurs clients pour id=' || p_id);
END;

Exceptions personnalisées

DECLARE
  solde_insuffisant EXCEPTION;
  v_solde NUMBER;
BEGIN
  SELECT solde INTO v_solde FROM comptes WHERE id = p_id;
  IF v_solde < p_montant THEN
    RAISE solde_insuffisant;
  END IF;
  -- ...
EXCEPTION
  WHEN solde_insuffisant THEN
    DBMS_OUTPUT.put_line('Solde insuffisant.');
END;

RAISE_APPLICATION_ERROR : renvoyer une erreur métier

Pour remonter une erreur claire à l’application appelante (codes de -20000 à -20999) :

RAISE_APPLICATION_ERROR(-20001, 'Le client ' || p_id || ' est introuvable.');

Associer une exception à un code ORA (EXCEPTION_INIT)

Pour capturer une erreur Oracle qui n’a pas de nom prédéfini :

DECLARE
  enfant_existe EXCEPTION;
  PRAGMA EXCEPTION_INIT(enfant_existe, -2292);  -- ORA-02292
BEGIN
  DELETE FROM clients WHERE id = p_id;
EXCEPTION
  WHEN enfant_existe THEN
    RAISE_APPLICATION_ERROR(-20020, 'Client référencé par des commandes.');
END;

SQLCODE, SQLERRM et la backtrace

EXCEPTION
  WHEN OTHERS THEN
    DBMS_OUTPUT.put_line('Code : '    || SQLCODE);
    DBMS_OUTPUT.put_line('Message : ' || SQLERRM);
    DBMS_OUTPUT.put_line(DBMS_UTILITY.format_error_backtrace);  -- ligne exacte
    RAISE;  -- re-lever : NE PAS avaler l'erreur
END;

La backtrace vous donne la ligne précise — utile pour diagnostiquer ORA-06512.

Les 4 règles d’or

  1. Ne jamais écrire WHEN OTHERS THEN NULL; : c’est avaler l’erreur silencieusement, le pire bug à débusquer.
  2. Un WHEN OTHERS doit logger ET re-lever (RAISE).
  3. Capturer les exceptions prévisibles nommément (NO_DATA_FOUND…), pas tout via OTHERS.
  4. Utiliser la plage -20000 à -20999 pour vos erreurs métier.

FAQ

WHEN OTHERS attrape-t-il toutes les erreurs ?

Presque : il capture toute exception non gérée avant lui. Mais il faut toujours logger et re-lever, sinon vous masquez la cause réelle.

Comment connaître le code d’une erreur dans le handler ?

SQLCODE renvoie le numéro (ex. -1403) et SQLERRM le message. Pour la ligne, utilisez DBMS_UTILITY.format_error_backtrace.

Peut-on continuer le traitement après une exception ?

Oui : placez le bloc BEGIN…EXCEPTION…END autour de la seule instruction risquée, à l’intérieur d’une boucle, pour traiter les autres lignes.

Publicité

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Publicité