【问题标题】:PL/SQL exception handling: do nothing (ignore exception)PL/SQL 异常处理:什么都不做(忽略异常)
【发布时间】:2015-02-18 10:30:30
【问题描述】:

这是我经常被问到的一个问题。由于我在 stackoverflow 上找不到任何确切的重复项,因此我想将其发布为参考。

问题: 在 PL/SQL 中,我知道如何捕获异常并在它们被捕获时执行代码,以及如何将它们传播到调用块。 例如,在以下过程中,NO_DATA_FOUND 异常被直接处理,而所有其他异常都被引发到调用块:

CREATE OR REPLACE PROCEDURE MY_PROCEDURE() 
IS
BEGIN
    do_stuff();

EXCEPTION
    WHEN NO_DATA_FOUND THEN
        -- Do something
        handle_exception();

    WHEN OTHERS THEN
        -- Propagate exception
        RAISE;
END;

但是我应该使用什么命令来忽略一个或所有引发的异常并将执行控制返回给调用块?

【问题讨论】:

    标签: oracle exception plsql exception-handling


    【解决方案1】:

    静默忽略异常确实有意义的另一种情况: 当您调用一个脚本时,如果该对象不存在,则该脚本会创建该对象,并且您没有该对象的创建或替换语法。 PLSQL 对象具有创建或替换语法,但表和索引没有。 然后我们可以将这些脚本放在一个块中并忽略引发的异常。

    【讨论】:

      【解决方案2】:

      虽然我同意 99% 的情况下,默默地忽略异常而不至少将它们记录在某处是不好的做法,但在某些特定情况下这是完全可以接受的。

      在这些情况下,NULL 是你的朋友:

      [...]
      EXCEPTION
      
          WHEN OTHERS THEN
              NULL;
      END;
      

      可能需要忽略异常的两种典型情况是:

      1) 您的代码包含一个您知道偶尔会失败的语句,并且您不希望这一事实中断您的程序流程。 在这种情况下,您应该将您的语句包含在一个嵌套块中,如下例所示:

      CREATE OR REPLACE PROCEDURE MY_PROCEDURE() 
      IS
          l_empoyee_name  EMPLOYEES.EMPLOYEE_NAME%TYPE;
      BEGIN
          -- Catch potential NO_DATA_FOUND exception and continue
          BEGIN 
              SELECT EMPLOYEE_NAME
              INTO l_empoyee_name
              FROM EMPLOYEES
              WHERE EMPLOYEE_ID = 12345;
          EXCEPTION
              WHEN NO_DATA_FOUND THEN
                  NULL;
              WHEN OTHERS THEN
                  RAISE;
          END;
      
          do_stuff();
      
      EXCEPTION
      
          WHEN OTHERS THEN
              -- Propagate exception
              RAISE;
      END;
      

      请注意,PL/SQL 通常不允许 Visual Basic 中已知的 On Error Resume Next 类型的异常处理,其中所有异常都被忽略,程序继续运行,就好像什么都没发生一样(请参阅On error resume next type of error handling in PL/SQL oracle)。您需要在嵌套块中显式地包含可能失败的语句。

      2) 您的过程是如此不重要,以至于忽略它抛出的所有异常都不会影响您的主程序逻辑。 (但是,这种情况很少发生,从长远来看,通常会导致调试噩梦)

      BEGIN
      
          do_stuff();
      
      EXCEPTION
      
          WHEN OTHERS THEN
              -- Ignore all exceptions and return control to calling block
              NULL;
      END;
      

      【讨论】:

      • 也许值得补充一点,when others then null 被认为是不好的做法,除非在非常特定的块中,您真的不关心步骤是否有效,而when others then raise 只是丢弃有关错误的信息。
      猜你喜欢
      • 1970-01-01
      • 2016-01-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-14
      • 2018-03-23
      • 1970-01-01
      相关资源
      最近更新 更多