質問は、マルチステートメントバッチスクリプトを示しています。 RAISE_APPLICATION_ERROR()は、PL / SQLブロック(サブプログラム)からのみ終了し、スクリプト全体(Justinが指摘)からは終了しないため、次のステートメントを続行します。
バッチスクリプトの場合は、WHENEVERSQLERROREXITを使用するのが最適です。はい、これはSQL Plusディレクティブであり、標準SQLではありませんが、かなり移植性があります。スクリプトをサポートする最も一般的なOracleツールは、少なくとも部分的にこのディレクティブをサポートします。次の例はSQLで機能します さらに、SQL * Developer、Toad、SQLsmithなどがあり、行をコメントアウトすると問題が発生します。
set serveroutput on
-- Without this line, things keep going
WHENEVER SQLERROR EXIT SQL.SQLCODE ROLLBACK;
BEGIN
IF (1 > 0) THEN
DBMS_OUTPUT.PUT_LINE('First thing');
RAISE_APPLICATION_ERROR(-20000, 'Test failed'); -- not enough
END IF;
END;
/
-- This will execute if you remove WHEN SQLERROR.., so RAISE_APPLICATION_ERROR is not enough
BEGIN
DBMS_OUTPUT.PUT_LINE('Second thing - Executes anyway');
END;
/
WHEN SQLERRORを削除すると、スクリプトは続行され、2番目のブロックなどが実行されます。これは、質問で回避するように求められているものです。
この場合、sqlplusをエミュレートするグラフィカルツールの利点は、スクリプトを実際に停止し、スクリプトの残りの部分をシェルコマンドとしてコマンドシェルに送信しないことです。これは、スクリプトをSQL<に貼り付けた場合に発生します。 em>Plusはコンソールウィンドウで実行されます。 SQL Plusはエラーで終了する場合がありますが、残りのバッファリングされたコマンドはOSシェルによって処理されます。これは、コメントにシェルコマンドが含まれている場合(前代未聞ではありません)、少し面倒で潜在的にリスクがあります。 SQLPlusでは、これを回避するために、接続してからスクリプトを実行するか、スクリプトを