如何跳过嵌套块中的异常

Posted

技术标签:

【中文标题】如何跳过嵌套块中的异常【英文标题】:How to skip exception in nested block 【发布时间】:2017-09-13 05:07:53 【问题描述】:

我的程序中有 2 个嵌套块。如果在第一个嵌套块中发生任何错误,则程序将不再执行,它将转到异常部分并退出整个程序。 但我不想退出我的程序。我的程序需要为第二个嵌套块执行,此外,甚至在第一个嵌套块中引发异常。

如果我有这样的程序:

DECLARE
    var_out VARCHAR2(10):= 'OUTER';
BEGIN
    <<INNER1>>
    DECLARE
        var_in1  NUMBER:='INNER 1';
    BEGIN
        DBMS_OUTPUT.PUT_LINE(var_in1);
    EXCEPTION
        WHEN OTHERS THEN
            DBMS_OUTPUT.PUT_LINE(SQLERRM);
    END;

    <<INNER2>>
    DECLARE
        var_in2 VARCHAR2(10):='INNER 2';
    BEGIN
        DBMS_OUTPUT.PUT_LINE(var_in2);
    EXCEPTION
        WHEN OTHERS THEN 
            DBMS_OUTPUT.PUT_LINE(SQLERRM);
    END;
    DBMS_OUTPUT.PUT_LINE(var_out);
EXCEPTION
    WHEN OTHERS THEN
        DBMS_OUTPUT.PUT_LINE(SQLERRM);
END;

在我的程序中,inner1 块将抛出value error exception,因此整个程序将不会被执行。

如何执行inner2和outer块,甚至inner1块中出现异常?

【问题讨论】:

【参考方案1】:

因为INNER1 中的异常发生在声明部分,它超出了块的异常处理程序的范围。您需要将整个 INNER1 块包装在另一个带有自己的异常处理程序的块中。

declare
    var_out varchar2(10):= 'OUTER';
begin
    <<INNER1>>
    begin
        declare
            var_in1  number:='INNER 1';
        begin
            dbms_output.put_line(var_in1);
        exception
            when others then
                dbms_output.put_line('Error in innermost INNER1');
        end;
    exception
        when others then
            dbms_output.put_line('Error in INNER1 wrapper');
    end;

    <<INNER2>>
    declare
        var_in2 varchar2(10):='INNER 2';
    begin
        dbms_output.put_line(var_in2);
    exception
        when others then 
            dbms_output.put_line('Error in INNER2');
    end;
    dbms_output.put_line(var_out);
exception
    when others then
        dbms_output.put_line('Error at top level');
end;

输出:

Error in INNER1 wrapper
INNER 2
OUTER

可能两个OTHERS 处理程序都不需要 - 以上只是为了说明结构。

【讨论】:

谢谢@william。一些文盲对我的问题投了反对票并说,这在 PL/SQL 中是不可能的。

以上是关于如何跳过嵌套块中的异常的主要内容,如果未能解决你的问题,请参考以下文章

如何从 PowerShell 中的 catch 块中重新引发异常?

异常块中的事务 - 如何?

为啥 C 预处理器不忽略它跳过的块中的无效指令?

检查 PL/SQL 异常块中的特定错误代码

如何使用多个catch块处理异常

ActiveRecord::Rollback 在嵌套的 begin-rescue 块中的行为方式