Oracle 11 - sqlplus - 在出错时回滚整个脚本 - 如何?

Grz*_*orz 5 sqlplus rollback oracle11g

如何使 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;
Run Code Online (Sandbox Code Playgroud)

并且使用“@”将该文件包含到 sqlplus 会话中:

@error.sql
Run Code Online (Sandbox Code Playgroud)

正如预期的那样,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
Run Code Online (Sandbox Code Playgroud)

但是当我重新启动 sqlplus 时,表 a 包含 2 条记录,这意味着在 sqlplus 退出时发生了提交而不是回滚。

我可以以某种方式强制 sqlplus:

  1. 出错时停止处理文件,
  2. 并在出错时回滚整个事务?

Daz*_*zaL 4

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;
/
Run Code Online (Sandbox Code Playgroud)