5

含まれている SQL ファイルにエラーが発生した場合に、Oracle 11g でトランザクション全体をロールバックするにはどうすればよいですか?

ファイルの内容は次のとおりです。

set autocommit off
whenever SQLERROR EXIT ROLLBACK

insert into a values (1);
insert into a values (2);

drop index PK_NOT_EXIST;

commit;

そして、ファイルは "@" を使用して sqlplus セッションに含まれます。

@error.sql

予想どおり、sqlplus セッションは終了し、出力は次のようになります。

SQL> @error.sql
1 row created.
1 row created.
drop index PK_NOT_EXIST           *
ERROR at line 1:
ORA-01418: specified index does not exist
Disconnected from Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options

しかし、sqlplus を再起動すると、テーブルには 2 つのレコードが含まれます。これは、sqlplus の終了時にロールバックではなくコミットがあったことを意味します。

どうにかしてsqlplusに次のことを強制できますか:

  1. エラー時にファイルの処理を停止し、
  2. エラー時にトランザクション全体をロールバックしますか?
4

2 に答える 2

4

私は問題を解決し、誰かがそのような問題に遭遇した場合に備えて、解決策を投稿します.

スクリプトに DDL コマンドを入れなければ、ロールバックは正しく実行されます。

したがって、スクリプトは次のとおりです。

set autocommit off
whenever SQLERROR EXIT ROLLBACK

insert into a values (1);
insert into a values (2);

insert into a values ('x');

commit;

動作します。

また、DDL が使用されている場合、通常、Oracle はロールバック機能を提供しません。

于 2013-02-08T09:53:34.610 に答える
3

DDL は実行前と実行後にコミットを実行するため、DDL が失敗した場合でも、オラクルはすでにトランザクションをコミットしています。

あなたはそれを回避することができます:

set autocommit off
whenever SQLERROR EXIT ROLLBACK


declare
  procedure drop_idx(i varchar2)  
  is
    pragma autonomous_transaction; -- this runs in its own transaction.
  begin
    execute immediate 'drop index ' || i;
  end;
begin
  insert into a values (1);
  insert into a values (2);
  drop_idx('PK_NOT_EXIST');
end;
/
于 2013-02-08T09:54:38.640 に答える