PL/SQL异常处理:什么都不做(忽略异常)

sil*_*fer 30 oracle plsql exception-handling exception

这是我经常被问到的一个问题.由于我在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;
Run Code Online (Sandbox Code Playgroud)

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

sil*_*fer 50

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

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

[...]
EXCEPTION

    WHEN OTHERS THEN
        NULL;
END;
Run Code Online (Sandbox Code Playgroud)

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

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;
Run Code Online (Sandbox Code Playgroud)

请注意,PL/SQL通常不允许从Visual Basic中获取On Error Resume Next类型的异常处理,其中忽略所有异常并且程序继续运行,就像没有发生任何事情一样(请参阅错误恢复下一类错误处理PL/SQL oracle).您需要在嵌套块中明确地包含可能失败的语句.

2)你的程序太不重要了,忽略它抛出的所有异常都不会影响你的主程序逻辑.(但是,这种情况很少发生,从长远来看经常会导致调试噩梦)

BEGIN

    do_stuff();

EXCEPTION

    WHEN OTHERS THEN
        -- Ignore all exceptions and return control to calling block
        NULL;
END;
Run Code Online (Sandbox Code Playgroud)

  • 也许值得补充的是,"当其他人然后为null"被认为是不好的做法,除非在非常具体的块中,你真的不关心步骤是否有效,以及"当其他人随后加注"只是抛弃有关错误的信息. (3认同)

小智 6

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