7

How can I make Oracle 11g rollback the whole transaction on any error in included SQL file?

The file contents are:

set autocommit off
whenever SQLERROR EXIT ROLLBACK

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

drop index PK_NOT_EXIST;

commit;

And the file is included into sqlplus session using "@":

@error.sql

As expected, the sqlplus session terminates and the output is

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

But when I re-launch sqlplus then the table a contains 2 records which means that there was a commit and not a rollback on exit of sqlplus.

Can I somehow force sqlplus to:

  1. stop processing file on error,
  2. and rollback the whole transaction on error?

2 Answers 2

5

DDL performs a commit before it runs and after so that even if your DDL fails, oracle will have already committed the transaction.

you could work around it with:

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;
/
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks. The problem with it is that DDLs that succeed will anyway be committed. So I will get it inconsistent any way. It seems that the only way to apply such a script is to do it step by step, stop on error, and after fixing it continue from where it failed.
4

I solved the issue and I post back the solution in case anyone hits such a problem.

If I don't put DDL commands in the script then the rollback is performed correctly.

So the script:

set autocommit off
whenever SQLERROR EXIT ROLLBACK

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

insert into a values ('x');

commit;

works.

And if DDL is used then in general Oracle does not provide rollback functionality.

1 Comment

To confirm, I just tested a case on 12c with some DDL followed by DML. If you execute ddl_statement; dml_statement_1; dml_statement_2; and there is an error in dmlstatement_2, then it will commit (of course) ddl_statement but rollback dml_statement_1 and dml_statement_2. (This turned out to be acceptable for our case.)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.