EXCEPTION (Exécution de scripts Snowflake)

Spécifie comment traiter les exceptions soulevées dans le bloc Exécution de scripts Snowflake.

Pour plus d’informations sur les exceptions, voir Traitement des exceptions.

Voir aussi

RAISE

Syntaxe

EXCEPTION
    WHEN <exception_name> [ OR <exception_name> ... ] THEN
        <statement>;
        [ <statement>; ... ]
    [ WHEN ... ]
    [ WHEN OTHER THEN ]
        <statement>;
        [ <statement>; ... ]
Copy

Où :

exception_name

Un nom d’exception défini dans la partie DECLARE du bloc actuel, ou dans un bloc englobant.

statement

Une instruction peut être l’un des éléments suivants :

  • Une seule instruction SQL (y compris CALL).

  • Une instruction de flux de contrôle (par exemple, instruction looping ou branching).

  • Un bloc imbriqué.

Notes sur l’utilisation

  • Chaque bloc peut avoir son propre gestionnaire d’exception.

  • Snowflake ne prend pas en charge plus d’un gestionnaire d’exception par bloc. Cependant, ce gestionnaire peut détecter plusieurs types d’exceptions en ayant plus d’une clause WHEN.

  • Le gestionnaire des exceptions doit se trouver à la fin du bloc. Si le bloc contient des instructions après le gestionnaire d’exception, ces instructions ne sont pas exécutées.

  • La clause WHEN OTHER THEN récupère toute exception non encore spécifiée.

  • Si plus d’une clause WHEN peut correspondre à une exception spécifique, c’est la première clause WHEN qui est exécutée. Les autres clauses ne sont pas exécutées.

  • Un gestionnaire d’exception ne peut traiter une exception spécifiée que si cette exception spécifiée se trouve dans le scope.

  • Si une procédure stockée est destinée à renvoyer une valeur, elle doit renvoyer une valeur à partir de chaque chemin possible, y compris chaque clause WHEN du gestionnaire d’exception.

Exemples

Cet exemple déclare, lève et gère une exception. Remarques importantes :

  • Le gestionnaire d’exceptions est conçu pour traiter plusieurs types d’exceptions.

  • L’une des clauses WHEN du gestionnaire d’exception contient une seule instruction, tandis que l’autre contient un bloc.

    DECLARE
      RESULT VARCHAR;
      EXCEPTION_1 EXCEPTION (-20001, 'I caught the expected exception.');
      EXCEPTION_2 EXCEPTION (-20002, 'Not the expected exception!');
    BEGIN
      RESULT := 'If you see this, I did not catch any exception.';
      IF (TRUE) THEN
        RAISE EXCEPTION_1;
      END IF;
      RETURN RESULT;
    EXCEPTION
      WHEN EXCEPTION_2 THEN
        RETURN SQLERRM;
      WHEN EXCEPTION_1 THEN
        RETURN SQLERRM;
    END;
    
    Copy

    Remarque : si vous utilisez SnowSQL ou l”Classic Console, utilisez cet exemple à la place (voir Utilisation d’Exécution de scripts Snowflake dans SnowSQL et l”Classic Console) :

    EXECUTE IMMEDIATE $$
        DECLARE
            RESULT VARCHAR;
            EXCEPTION_1 EXCEPTION (-20001, 'I caught the expected exception.');
            EXCEPTION_2 EXCEPTION (-20002, 'Not the expected exception!');
        BEGIN
            RESULT := 'If you see this, I did not catch any exception.';
            IF (TRUE) THEN
                RAISE EXCEPTION_1;
            END IF;
            RETURN RESULT;
        EXCEPTION
            WHEN EXCEPTION_2 THEN
                RETURN SQLERRM;
            WHEN EXCEPTION_1 THEN
                RETURN SQLERRM;
        END;
    $$
    ;
    
    Copy

Voici le résultat de l’exécution de l’exemple qui soulève l’exception. Cela montre que le gestionnaire d’exceptions a décelé l’exception.

+----------------------------------+
| anonymous block                  |
|----------------------------------|
| I caught the expected exception. |
+----------------------------------+
Copy

L’exemple suivant est similaire au précédent, mais présente des blocs imbriqués et montre qu’un bloc interne peut soulever une exception déclarée soit dans le bloc interne, soit dans un bloc externe.

DECLARE
  e1 EXCEPTION (-20001, 'Exception e1');

BEGIN
  -- Inner block.
  DECLARE
    e2 EXCEPTION (-20002, 'Exception e2');
    selector BOOLEAN DEFAULT TRUE;
  BEGIN
    IF (selector) THEN
      RAISE e1;
    ELSE
      RAISE e2;
    END IF;
  END;

EXCEPTION
  WHEN e1 THEN
    RETURN SQLERRM || ' caught in outer block.';
END;
Copy

Remarque : si vous utilisez SnowSQL ou l”Classic Console, utilisez cet exemple à la place (voir Utilisation d’Exécution de scripts Snowflake dans SnowSQL et l”Classic Console) :

EXECUTE IMMEDIATE $$
    DECLARE
        e1 EXCEPTION (-20001, 'Exception e1');

    BEGIN
        -- Inner block.
        DECLARE
            e2 EXCEPTION (-20002, 'Exception e2');
            selector BOOLEAN DEFAULT TRUE;
        BEGIN
            IF (selector) THEN
                RAISE e1;
            ELSE
                RAISE e2;
            END IF;
        END;

    EXCEPTION
        WHEN e1 THEN
            BEGIN
                RETURN SQLERRM || ' caught in outer block.';
            END;

    END;
$$
;
Copy

Voici le résultat de l’exécution de l’exemple qui soulève l’exception. Cela montre que le gestionnaire d’exceptions a décelé l’exception.

+-------------------------------------+
| anonymous block                     |
|-------------------------------------|
| Exception e1 caught in outer block. |
+-------------------------------------+
Copy

L’exemple suivant est similaire à l’exemple précédent, mais présente des blocs imbriqués, dont chacun possède son propre gestionnaire d’exceptions.

DECLARE
  RESULT VARCHAR;
  e1 EXCEPTION (-20001, 'Outer exception e1');

BEGIN
  RESULT := 'No error so far (but there will be).';

  DECLARE
    e1 EXCEPTION (-20101, 'Inner exception e1');
  BEGIN
    RAISE e1;
  EXCEPTION
    WHEN e1 THEN
      RESULT := 'Inner exception raised.';
      RETURN RESULT;
  END;

  RETURN RESULT;

EXCEPTION
  WHEN e1 THEN
    RESULT := 'Outer exception raised.';
    RETURN RESULT;

END;
Copy

Remarque : si vous utilisez SnowSQL ou l”Classic Console, utilisez cet exemple à la place (voir Utilisation d’Exécution de scripts Snowflake dans SnowSQL et l”Classic Console) :

EXECUTE IMMEDIATE $$
    DECLARE
        RESULT VARCHAR;
        e1 EXCEPTION (-20001, 'Outer exception e1');

    BEGIN
        RESULT := 'No error so far (but there will be).';

        DECLARE
            e1 EXCEPTION (-20101, 'Inner exception e1');
        BEGIN
            RAISE e1;
        EXCEPTION
            WHEN e1 THEN
                RESULT := 'Inner exception raised.';
                RETURN RESULT;
        END;

        RETURN RESULT;

    EXCEPTION
        WHEN e1 THEN
            RESULT := 'Outer exception raised.';
            RETURN RESULT;

    END;
$$
;
Copy

Note

Cet exemple utilise le même nom d’exception (e1) dans les blocs externe et interne.

Ce n’est pas recommandé.

L’exemple fait cela pour illustrer le scope des noms d’exception. Les deux exceptions portant le nom e1 sont des exceptions différentes.

Le gestionnaire e1 du bloc externe ne traite pas l’exception e1 qui est déclarée et soulevée dans le bloc interne.

Voici le résultat de l’exécution de l’exemple qui soulève l’exception. Cela montre que le gestionnaire d’exception interne s’est exécuté.

+-------------------------+
| anonymous block         |
|-------------------------|
| Inner exception raised. |
+-------------------------+
Copy

Ce fragment d’exemple montre :

  • Comment détecter plus d’une exception dans la même clause en utilisant OR.

  • Comment détecter des exceptions non spécifiées en utilisant WHEN OTHER THEN.

    EXCEPTION
      WHEN MY_FIRST_EXCEPTION OR MY_SECOND_EXCEPTION OR MY_THIRD_EXCEPTION THEN
        RETURN 123;
      WHEN MY_FOURTH_EXCEPTION THEN
        RETURN 4;
      WHEN OTHER THEN
        RETURN 99;
    
    Copy

L’exemple suivant montre comment retourner SQLCODE, SQLERRM (message d’erreur SQL), et SQLSTATE lors de la capture d’une exception :

DECLARE
  MY_EXCEPTION EXCEPTION (-20001, 'Sample message');
BEGIN
  RAISE MY_EXCEPTION;
EXCEPTION
  WHEN STATEMENT_ERROR THEN
    RETURN OBJECT_CONSTRUCT('Error type', 'STATEMENT_ERROR',
                            'SQLCODE', SQLCODE,
                            'SQLERRM', SQLERRM,
                            'SQLSTATE', SQLSTATE);
  WHEN EXPRESSION_ERROR THEN
    RETURN OBJECT_CONSTRUCT('Error type', 'EXPRESSION_ERROR',
                            'SQLCODE', SQLCODE,
                            'SQLERRM', SQLERRM,
                            'SQLSTATE', SQLSTATE);
  WHEN OTHER THEN
    RETURN OBJECT_CONSTRUCT('Error type', 'Other error',
                            'SQLCODE', SQLCODE,
                            'SQLERRM', SQLERRM,
                            'SQLSTATE', SQLSTATE);
END;
Copy

Remarque : si vous utilisez SnowSQL ou l”Classic Console, utilisez cet exemple à la place (voir Utilisation d’Exécution de scripts Snowflake dans SnowSQL et l”Classic Console) :

EXECUTE IMMEDIATE $$
    DECLARE
        MY_EXCEPTION EXCEPTION (-20001, 'Sample message');
    BEGIN
        RAISE MY_EXCEPTION;
    EXCEPTION
        WHEN STATEMENT_ERROR THEN
            RETURN OBJECT_CONSTRUCT('Error type', 'STATEMENT_ERROR',
                                    'SQLCODE', SQLCODE,
                                    'SQLERRM', SQLERRM,
                                    'SQLSTATE', SQLSTATE);
        WHEN EXPRESSION_ERROR THEN
            RETURN OBJECT_CONSTRUCT('Error type', 'EXPRESSION_ERROR',
                                    'SQLCODE', SQLCODE,
                                    'SQLERRM', SQLERRM,
                                    'SQLSTATE', SQLSTATE);
        WHEN OTHER THEN
            RETURN OBJECT_CONSTRUCT('Error type', 'Other error',
                                    'SQLCODE', SQLCODE,
                                    'SQLERRM', SQLERRM,
                                    'SQLSTATE', SQLSTATE);
    END;
$$
;
Copy

L’exécution de cet exemple produit le résultat suivant :

+--------------------------------+
| anonymous block                |
|--------------------------------|
| {                              |
|   "Error type": "Other error", |
|   "SQLCODE": -20001,           |
|   "SQLERRM": "Sample message", |
|   "SQLSTATE": "P0001"          |
| }                              |
+--------------------------------+
Copy

Cet exemple montre comment renvoyer une valeur à partir de chaque chemin possible :

declare
    e1 exception;
    e2 exception;
begin
    statement_1;
    ...
    RETURN x;
exception
    when e1 then begin
        ...
        RETURN y;
        end;
    when e2 then begin
        ...
        RETURN z;
        end;
end;
Copy