
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.
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
| Exception | Erreur Oracle | Quand |
|---|---|---|
NO_DATA_FOUND | ORA-01403 | SELECT INTO ne ramène aucune ligne |
TOO_MANY_ROWS | ORA-01422 | SELECT INTO ramène > 1 ligne |
DUP_VAL_ON_INDEX | ORA-00001 | doublon sur contrainte unique |
VALUE_ERROR | ORA-06502 | conversion / taille de variable |
ZERO_DIVIDE | ORA-01476 | division 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
- Ne jamais écrire
WHEN OTHERS THEN NULL;: c’est avaler l’erreur silencieusement, le pire bug à débusquer. - Un
WHEN OTHERSdoit logger ET re-lever (RAISE). - Capturer les exceptions prévisibles nommément (NO_DATA_FOUND…), pas tout via OTHERS.
- 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.
