5

如何让 Oracle 11g 在包含的 SQL 文件中出现任何错误时回滚整个事务?

文件内容为:

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 时,表 a 包含 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 失败,oracle 也已经提交了事务。

你可以解决它:

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 回答