スクリプトを終了してSQL*Plusにとどまることができませんが、実行を停止することはできます。きれいではありませんが、スクリプトを変更して制御フローを追加できると仮定すると、バインド変数を使用してこれを実行できます。
set serveroutput on
var flag char;
exec :flag := 'Y';
begin
if :flag != 'Y' then
raise program_error;
end if;
dbms_output.put_line('Doing some work');
/* Check for some error condition */
if 0 != 1 then
raise program_error;
end if;
/* Only reach this if earlier statements didn't fail
* but could wrap in another flag check if needed */
dbms_output.put_line('Doing some more work');
exception
when program_error then
dbms_output.put_line(sqlerrm);
:flag := 'N';
when others then
/* Real exception handling, obviously */
dbms_output.put_line(sqlerrm);
:flag := 'N';
end;
/
-- DML only does anything if flag stayed Y
select sysdate from dual
where :flag = 'Y';
-- Optional status message at the end of the script, for DBA info
set feedback off
set head off
select 'Something went wrong' from dual where :flag != 'Y';
set feedback on
set head on
実行時:
SQL> @script
PL/SQL procedure successfully completed.
Doing some work
ORA-06501: PL/SQL: program error
PL/SQL procedure successfully completed.
no rows selected
Something went wrong
SQL>
スクリプト内のすべてのPL/SQLブロックは、開始時にフラグのステータスをチェックし、program_error
(便利な事前定義された例外として)発生して元に戻ることができます。PL / SQLブロック内でエラーが発生すると、直接または例外ハンドラでバインド変数フラグが更新される可能性があります。また、PL / SQL以外のDMLにはwhere
、フラグのステータスをチェックするための追加の句を含めることができるためN
、ステートメントに到達するまでにフラグが設定されている場合、作業は行われません。(insert
私はそれがvalues
フォームを使用しないことを意味すると思います)。
これができないのは、プレーンSQLステートメントからのエラーを処理することですが、それが問題であるかどうかはわかりません。その場合は、PL/SQLブロック内で動的SQLに変更する必要があります。