有条件的插入和回滚

时间:2018-03-30 16:16:35

标签: oracle insert

我有三个插入语句A,b和C,它们将按顺序执行。如果A失败,则C必须失败,反之亦然。如何处理这种情况?

1 个答案:

答案 0 :(得分:0)

创建表:

drop table mytab;
create table mytab(v varchar2(10));

使用自治事务的过程:即使外部事务被回滚,自治事务也允许提交嵌套事务。

create or replace procedure sp_tranB as
pragma autonomous_transaction;--runs as a separate transaction and commits irrespective of outer transaction
begin
    insert into mytab values('Insert B');
    commit;
exception when others
          then null;
end;

场景:所有插入成功。

declare
    a_status number;
begin
    a_status := 0;
    begin
        insert into mytab values('Insert A');
        --do not commit here. This allows rollback if C fails.
    exception when others
              then a_status := 1;
    end;

    begin
        sp_tranB;
    end;

    if a_status = 0 then
    begin
        insert into mytab values('Insert C');
        commit;
    exception when others
              then rollback;
    end;
    end if;

end;

select * from mytab;

输出:

V
Insert A
Insert B
Insert C

truncate table mytab;

场景:A失败并阻止C

declare
    a_status number;
begin
    a_status := 0;
    begin
        insert into mytab values('Insert A too large');--A fails
        --do not commit here. This allows rollback if C fails.
    exception when others
              then a_status := 1;
    end;

    begin
        sp_tranB;
    end;

    if a_status = 0 then--C must not execute as A fails
    begin
        insert into mytab values('Insert C');
        commit;
    exception when others
              then rollback;
    end;
    end if;

end;

select * from mytab;

输出:

V
Insert B

truncate table mytab;

场景:C失败并回滚A

declare
    a_status number;
begin
    a_status := 0;
    begin
        insert into mytab values('Insert A');
        --do not commit here. This allows rollback if C fails.
    exception when others
              then a_status := 1;
    end;

    begin
        sp_tranB;
    end;

    if a_status = 0 then
    begin
        insert into mytab values('Insert C too large');--C fail and....
        commit;
    exception when others
              then rollback;
              --...rollsback A
    end;
    end if;

end;

select * from mytab;

输出:

V
Insert B

注意:不建议用" WHEN OTHERS NULL;"来抑制异常。不要在您的应用程序中使用它。此处仅用于演示针对此特定要求的自治事务的功能。