ORAコードの場合にロールバック/追加の処理を行う場合は、すべてSQL*PLUSセッションで実行します。
つまり、スクリプトとして実行します。
set serverout on
begin
update...;
exception
when others -- others is a catch all, you can catch specific codes too
then
rollback;
dbms_output.put_line('Error!');
dbms_output.put_line(sqlerrm); -- prints full error string
end;
/
sqlステートメントが失敗したことをbashに通知したいだけの場合は、sql*plusの最初のものとして設定できます。whenever sqlerror exit sql.sqlcode
(またはwhenever sqlerror (exit -1
など)代わりに(ここを参照)。これは最初のエラーで停止し、適切なリターンコードを使用してシェルスクリプトに戻ります。
ブロックをネストできます。例:
begin
update ..;
begin
select id into v_id
from tab
where ...;
exception
when no_data_found
then
null;-- ignore that we didnt find a row
end;
-- if the select fails, we continue from here..
delete...;
begin
savepoint mysave;
your_proc(...);
exception
when others
then
rollback to mysave; -- of the call to your_proc fails, lets just toll that back alone
end;
end;
等
インタラクティブにする必要がある場合は、(dbms_alert)[http://docs.oracle.com/cd/B19306_01/appdev.102/b14258/d_alert.htm#CHDCFHCI]のように実行できます。
sqlplus /<<EOF | tee -a my.log
set feedback on verify on serverout on
-- IE YOUR CODE HERE..
select * from dual;
begin
null;
end;
/
-- END OF YOUR CODE..
-- now lets wait for an alert from another session:
declare
v_message varchar2(32767);
v_status number;
begin
DBMS_ALERT.REGISTER('should_i_commit');
DBMS_ALERT.WAITONE('should_i_commit', v_message, v_status); -- there is a timeout parameter you can set too
if (v_message = 'Y')
then
dbms_output.put_line('I committed');
commit;
else
dbms_output.put_line('I rolled back');
rollback;
end if;
end;
/
EOF
次に、別のセッションで次を発行できます。
SQL> exec dbms_alert.signal('should_i_commit', 'N');
PL/SQL procedure successfully completed.
SQL> commit;
Commit complete.