EXCEPTION (Snowflakeスクリプト)¶
Snowflakeスクリプトのブロックで発生した例外の処理方法を指定します。
例外の詳細については、 処理の例外 をご参照ください。
- こちらもご参照ください:
構文¶
EXCEPTION
WHEN <exception_name> [ OR <exception_name> ... ] THEN
<statement>;
[ <statement>; ... ]
[ WHEN ... ]
[ WHEN OTHER THEN ]
<statement>;
[ <statement>; ... ]
条件:
exception_name
現在のブロックの DECLARE 部分、またはそれを囲むブロックで定義された例外名。
使用上の注意¶
各 ブロック は、独自の例外ハンドラーを持つことができます。
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;
注: 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; $$ ;
これは、例外が発生する例を実行した結果です。これは、例外ハンドラーが例外をキャッチしたことを示しています。
+----------------------------------+ | anonymous block | |----------------------------------| | I caught the expected exception. | +----------------------------------+
次の例は前の例と似ていますが、ネストされたブロックを示し、内側のブロックが、内側のブロックまたは外側のブロックのいずれかで宣言された例外の発生する可能性があることを示しています。
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;注: 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; $$ ;
これは、例外が発生する例を実行した結果です。これは、例外ハンドラーが例外をキャッチしたことを示しています。
+-------------------------------------+ | anonymous block | |-------------------------------------| | Exception e1 caught in outer block. | +-------------------------------------+
次の例は前の例と似ていますが、ネストされたブロックを示しています。各ブロックには独自の例外ハンドラーがあります。
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;注: 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; $$ ;
注釈
この例では、外側のブロックと内側のブロックで同じ例外名(e1
)を使用しています。
これはお勧めしません。
この例では、例外名の スコープ を説明するためにこれを実行しています。 e1
という名前の2つの例外は、異なる例外です。
外側のブロックの e1
ハンドラーは、内側のブロックで宣言および発生した例外e1を処理しません。
これは、例外が発生する例を実行した結果です。これは、内側の例外ハンドラーが実行されたことを示しています。
+-------------------------+ | anonymous block | |-------------------------| | Inner exception raised. | +-------------------------+
このフラグメントの例は次を示しています。
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;
次の例は、例外をキャッチしたときに 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;注: 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; $$ ;
この例を実行すると、次の出力が生成されます。
+--------------------------------+ | anonymous block | |--------------------------------| | { | | "Error type": "Other error", | | "SQLCODE": -20001, | | "SQLERRM": "Sample message", | | "SQLSTATE": "P0001" | | } | +--------------------------------+
この例は、 それぞれ の可能なパスから値を返す方法を示しています。
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;