web-dev-qa-db-fra.com

Gestion des exceptions PL / SQL: ne rien faire (ignorer l'exception)

C'est une question que l'on me pose très fréquemment. Comme je n'ai pas pu trouver de doublon exact sur stackoverflow, j'ai pensé le poster comme référence.

Question: En PL/SQL, je sais comment intercepter des exceptions et exécuter du code lorsqu'elles sont interceptées, et comment les propager vers le bloc appelant. Par exemple, dans la procédure suivante, l'exception NO_DATA_FOUND est gérée directement, tandis que toutes les autres exceptions sont levées vers le bloc appelant:

CREATE OR REPLACE PROCEDURE MY_PROCEDURE() 
IS
BEGIN
    do_stuff();

EXCEPTION
    WHEN NO_DATA_FOUND THEN
        -- Do something
        handle_exception();

    WHEN OTHERS THEN
        -- Propagate exception
        RAISE;
END;

Mais quelle commande dois-je utiliser pour ignorer une ou toutes les exceptions levées et retourner le contrôle d'exécution au bloc appelant?

28
silentsurfer

Bien que je convienne que 99% du temps, il est une mauvaise pratique d'ignorer silencieusement les exceptions sans au moins les enregistrer quelque part, il existe des situations spécifiques où cela est parfaitement acceptable.

Dans ces situations, NULL est votre ami:

[...]
EXCEPTION

    WHEN OTHERS THEN
        NULL;
END;

Deux situations typiques où ignorer les exceptions peuvent être souhaitables sont:

1) Votre code contient une déclaration qui, vous le savez, échouera occasionnellement et vous ne voulez pas que ce fait interrompe le flux de votre programme. Dans ce cas, vous devez placer votre instruction dans un bloc imbriqué, comme le montre l'exemple suivant:

CREATE OR REPLACE PROCEDURE MY_PROCEDURE() 
IS
    l_empoyee_name  EMPLOYEES.EMPLOYEE_NAME%TYPE;
BEGIN
    -- Catch potential NO_DATA_FOUND exception and continue
    BEGIN 
        SELECT EMPLOYEE_NAME
        INTO l_empoyee_name
        FROM EMPLOYEES
        WHERE EMPLOYEE_ID = 12345;
    EXCEPTION
        WHEN NO_DATA_FOUND THEN
            NULL;
        WHEN OTHERS THEN
            RAISE;
    END;

    do_stuff();

EXCEPTION

    WHEN OTHERS THEN
        -- Propagate exception
        RAISE;
END;

Notez que PL/SQL ne permet généralement pas le type de gestion des exceptions On Error Resume Next connu de Visual Basic, où toutes les exceptions sont ignorées et le programme continue de s'exécuter comme si de rien n'était (voir On error resume next type de la gestion des erreurs dans PL/SQL Oracle ). Vous devez inclure explicitement les instructions potentiellement défaillantes dans un bloc imbriqué.

2) Votre procédure est si peu importante que le fait d'ignorer toutes les exceptions qu'elle déclenche n'affectera pas la logique de votre programme principal. (Cependant, c'est très rarement le cas et peut souvent entraîner un cauchemar de débogage à long terme)

BEGIN

    do_stuff();

EXCEPTION

    WHEN OTHERS THEN
        -- Ignore all exceptions and return control to calling block
        NULL;
END;
48
silentsurfer

Un autre scénario où il est logique d'ignorer silencieusement l'exception: lorsque vous appelez un script censé créer un objet s'il n'existe pas et que vous n'avez pas de syntaxe de création ou de remplacement pour cet objet. Les objets PLSQL ont une syntaxe de création ou de remplacement, mais pas les tables et les index. Ensuite, nous pouvons mettre ces scripts dans un bloc et ignorer l'exception déclenchée.

2
Ananth N