EXCEPTION (Snowflakeスクリプト)

Snowflakeスクリプトのブロックで発生した例外の処理方法を指定します。

例外の詳細については、 処理の例外 をご参照ください。

こちらもご参照ください:

RAISE

構文

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

条件:

exception_name

現在のブロックの DECLARE 部分、またはそれを囲むブロックで定義された例外名。

statement

ステートメントは、次のいずれかになります。

  • 単一の SQL ステートメント(CALL を含む)。

  • 制御フローステートメント(例: ループ または 分岐 ステートメント)。

  • ネストされた ブロック

使用上の注意

  • ブロック は、独自の例外ハンドラーを持つことができます。

  • Snowflakeは、ブロックごとに1つだけの例外ハンドラーをサポートします。ただし、そのハンドラーは、複数の WHEN 句を使用することで、複数のタイプの例外をキャッチできます。

  • 例外ハンドラーはブロックの最後にある必要があります。例外ハンドラーの後に、ステートメントがブロックに含まれている場合、それらのステートメントは実行されません。

  • WHEN OTHER THEN 句は、まだ指定されていない例外をキャッチします。

  • 複数の WHEN 句が特定の例外に一致する可能性がある場合は、一致する最初の WHEN 句が実行されます。他の句は実行されません。

  • 例外ハンドラーは、指定された例外が スコープ にある場合にのみ、指定された例外を処理できます。

  • ストアドプロシージャが値を返すことを目的としている場合は、例外ハンドラーの WHEN 句を含む、可能な各パスから値を返す必要があります。

この例は、例外を宣言、発生、および処理します。注意:

  • 例外ハンドラーは、複数のタイプの例外を処理するように設計されています。

  • 例外ハンドラーの WHEN 句の1つには単一のステートメントが含まれ、もう1つには ブロック が含まれます。

    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

    注: SnowSQL または Classic Console を使用している場合は、代わりに次の例を使用します(SnowSQL および Classic Console でのSnowflakeスクリプトの使用 を参照)。

    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

これは、例外が発生する例を実行した結果です。これは、例外ハンドラーが例外をキャッチしたことを示しています。

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

次の例は前の例と似ていますが、ネストされたブロックを示し、内側のブロックが、内側のブロックまたは外側のブロックのいずれかで宣言された例外の発生する可能性があることを示しています。

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

注: SnowSQL または Classic Console を使用している場合は、代わりに次の例を使用します(SnowSQL および Classic Console でのSnowflakeスクリプトの使用 を参照)。

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

これは、例外が発生する例を実行した結果です。これは、例外ハンドラーが例外をキャッチしたことを示しています。

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

次の例は前の例と似ていますが、ネストされたブロックを示しています。各ブロックには独自の例外ハンドラーがあります。

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

注: SnowSQL または Classic Console を使用している場合は、代わりに次の例を使用します(SnowSQL および Classic Console でのSnowflakeスクリプトの使用 を参照)。

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

注釈

この例では、外側のブロックと内側のブロックで同じ例外名(e1)を使用しています。

これはお勧めしません。

この例では、例外名の スコープ を説明するためにこれを実行しています。 e1 という名前の2つの例外は、異なる例外です。

外側のブロックの e1 ハンドラーは、内側のブロックで宣言および発生した例外e1を処理しません。

これは、例外が発生する例を実行した結果です。これは、内側の例外ハンドラーが実行されたことを示しています。

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

このフラグメントの例は次を示しています。

  • OR を使用して、同じ句で複数の例外をキャッチする方法。

  • 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

次の例は、例外をキャッチしたときに SQLCODE、 SQLERRM(SQL エラーメッセージ)、および SQLSTATE を返す方法を示しています。

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

注: SnowSQL または Classic Console を使用している場合は、代わりに次の例を使用します(SnowSQL および Classic Console でのSnowflakeスクリプトの使用 を参照)。

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

この例を実行すると、次の出力が生成されます。

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

この例は、 それぞれ の可能なパスから値を返す方法を示しています。

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