Oracle11g oracle11-sqlplus-在出错时回滚整个脚本-如何?
如何使Oracle 11g在包含的SQL文件中出现任何错误时回滚整个事务 文件内容包括:Oracle11g oracle11-sqlplus-在出错时回滚整个脚本-如何?,oracle11g,sqlplus,rollback,Oracle11g,Sqlplus,Rollback,如何使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会话中: 正如预期的那样,sqlplus会话终止,输出也将停止 SQL> @error
set autocommit off
whenever SQLERROR EXIT ROLLBACK
insert into a values (1);
insert into a values (2);
drop index PK_NOT_EXIST;
commit;
并使用“@”将文件包含到sqlplus会话中:
正如预期的那样,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执行以下操作:
我解决了这个问题,并将解决方案发回,以防有人遇到这样的问题 如果我没有在脚本中放入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不提供回滚功能。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;
/
谢谢问题是成功的DDL无论如何都会被提交。所以我无论如何都会得到它。似乎应用这样一个脚本的唯一方法是一步一步地执行,在出现错误时停止,然后在修复后从失败的地方继续。为了确认,我刚刚在12c上测试了一个案例,其中包含一些DDL,后面是DML。如果执行
ddl_语句;dml_声明_1;dml_声明_2
如果dmlstatement_2中有错误,那么它将提交(当然)ddl_语句
,但回滚dml_语句_1
和dml_语句_2
。(这对于我们的案例来说是可以接受的。)
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;
/