Oracle 嵌套块和异常处理

Posted

技术标签:

【中文标题】Oracle 嵌套块和异常处理【英文标题】:Oracle nested blocks and exception handling 【发布时间】:2013-11-26 13:10:14 【问题描述】:
DECLARE
    string_of_5_chars VARCHAR2(5);
BEGIN
    BEGIN
        string_of_5_chars := 'Steven';
    EXCEPTION
        WHEN value_error THEN
          RAISE no_data_found;
        WHEN no_data_found THEN
          dbms_output.Put_line ('Inner block');
    END;
EXCEPTION
    WHEN no_data_found THEN
      dbms_output.Put_line ('Outer block');
END; 

答案说输出将是“外部块”,有人可以解释为什么内部块不会被执行吗? oracle中异常的优先级是什么

【问题讨论】:

您是否尝试下载 Oracle Express Edition 和 SQL Developer(均免费)并调试此 PL/SQL 块的执行? 【参考方案1】:
DECLARE
string_of_5_chars VARCHAR2(5);
BEGIN
BEGIN
    string_of_5_chars := 'Steven';  -- Varchar has a size of 5 defined above. So it will throw a value_error(due to size constraints) exception.
EXCEPTION
    WHEN value_error THEN    -- This exception block will handle the error thrown above.
      RAISE no_data_found;   -- It raises a no_data _found exception which by rule has to be handled in the outer exception block. So it goes to the outer exception block.
    WHEN no_data_found THEN
      dbms_output.Put_line ('Inner block');
END;
EXCEPTION
WHEN no_data_found THEN
  dbms_output.Put_line ('Outer block'); -- Exception is handled here which causes it to print 'Outer Block'
END;

阅读here 了解有关嵌套异常块的更多信息。

【讨论】:

【参考方案2】:

您应该将异常块的 WHEN 子句视为类似于常规 CASE 语句。执行第一个匹配条件的 WHEN,并跳过该异常处理程序中的以下 WHEN 子句。

因此内部异常块中的第二个 WHEN 子句根本不在代码执行路径中,而外部异常块捕获嵌套异常的第一个 WHEN 子句引发的 no_data_found 错误。

这里解释了这种情况下的异常传播:http://docs.oracle.com/cd/B28359_01/appdev.111/b28370/errors.htm#LNPLS00706

【讨论】:

【参考方案3】:

string_of_5_chars := 'Steven'; 引发value_error 时,会进入相应的异常块。 在 Exception 块内会引发 no_data_found Exception。由于引发部分,此异常随后由外部块的异常处理来处理。

更多信息请查看http://docs.oracle.com/cd/B19306_01/appdev.102/b14261/raise_statement.htm

【讨论】:

以上是关于Oracle 嵌套块和异常处理的主要内容,如果未能解决你的问题,请参考以下文章

Try/catch 块和未处理的承诺异常

java7 异常处理增强

oracle PLSQL块和复合类型

Java 处理异常

异常处理的性能开销

Java多层嵌套异常处理的基本流程