これは非常に頻繁に聞かれる質問です。私はstackoverflowで正確な複製を見つけることができなかったので、参考として投稿したいと思いました。
質問:PL/SQLでは、例外をキャッチし、キャッチされたときにコードを実行する方法と、それらを呼び出しブロックに伝播する方法を知っています。たとえば、次の手順では、NO_DATA_FOUND例外は直接処理されますが、他のすべての例外は呼び出しブロックに対して発生します。
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;
しかし、発生した1つまたはすべての例外を無視し、実行制御を呼び出しブロックに戻すには、どのコマンドを使用すればよいですか?
例外を少なくともどこかに記録せずに黙って無視することは悪い習慣であることに私は同意しますが、これが完全に受け入れられる特定の状況があります。
これらの状況では、NULLが友達です。
[...]
EXCEPTION
WHEN OTHERS THEN
NULL;
END;
例外を無視することが望ましい2つの典型的な状況は次のとおりです。
1)コードには、ときどき失敗することがわかっているステートメントが含まれており、この事実によってプログラムフローが中断されることは望ましくありません。この場合、次の例に示すように、ネストされたブロックでステートメントを囲む必要があります。
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;
通常、PL/SQLでは、Visual Basicで知られているOn Error Resume Nextタイプの例外処理は許可されず、すべての例外が無視され、プログラムは何も起こらなかったように実行され続けます( On error resume next type PL/SQL Oracleでのエラー処理の例 )。入れ子になったブロックで、潜在的に失敗するステートメントを明示的に囲む必要があります。
2)プロシージャはあまり重要ではないため、スローするすべての例外を無視してもメインプログラムのロジックには影響しません。 (ただし、これは非常にまれなケースであり、長期的にはデバッグの悪夢になることがよくあります)
BEGIN
do_stuff();
EXCEPTION
WHEN OTHERS THEN
-- Ignore all exceptions and return control to calling block
NULL;
END;
例外を静かに無視することが理にかなっている別のシナリオ:オブジェクトが存在しない場合にオブジェクトを作成することが期待され、そのオブジェクトの作成または置換構文がないスクリプトを呼び出すとき。 PLSQLオブジェクトには作成または置換構文がありますが、表および索引にはありません。次に、そのようなスクリプトをブロックに入れて、発生した例外を無視できます。