PL/SQL 过程中的异常处理

Posted

技术标签:

【中文标题】PL/SQL 过程中的异常处理【英文标题】:PL/SQL Exception handling in procedures 【发布时间】:2011-09-09 10:52:34 【问题描述】:

这是一个关于最佳实践的问题。我有一个类似的 PL/SQL 块

DECLARE

    --work variables

    PROCEDURE p1(in_parameter1, out_parameter1, out_parameter2...) IS
    BEGIN    
        --do stuff
        --select ( ... ) into ( ... ) from t1 where ( ... )
    END;

    PROCEDURE p2(in_parameter1, out_parameter1, out_parameter2...) IS
    BEGIN 
        --do stuff
        --insert/update tables
        --do more stuff
    END;    

BEGIN -- MAIN PROCESS STARTS HERE

    open c1;
    fetch c1 into c1RowData;
    EXIT WHEN c1%NOTFOUND    
     --call procedure1
     --do stuff
     --call procedure2
     --do stuff
     --do stuff
     --call procedure1
     --call procedure2
END;
/
EXIT;

过程 p1 和 p2 中的语句可能会引发异常(NO_DATA_FOUND、DUP_VAL_ON_INDEX、...)。

您认为处理这种异常的最佳方法是什么?它们应该在程序内部处理,还是您认为我应该用 TRY-CATCH 块围绕主体中的程序的每个调用?

【问题讨论】:

【参考方案1】:

就我个人而言,我会在它们被抛出的程序中捕获它们。这意味着您可以更好地控制它们在外部的处理方式。例如,您可以将它们作为用户定义的异常再次抛出,您可以使用更多关于究竟出了什么问题的信息来修饰它们。

'Failed to find a matching row in table a for value b'

在过程之外比

更具描述性
'no data found'

但这真的取决于:

    调用应用程序的错误报告要求 在程序中“做事”的地方实现的实际功能

例如,假设您想运行过程 2,即使过程 1 中的选择没有找到任何行。您需要捕获过程 1 中的异常并忽略它。如果你不这样做,那么它将被抛出到过程 2 中的异常处理程序。

或者,假设您希望过程 1 在 select 没有找到任何内容的情况下插入一行,在这种情况下,您需要捕获异常并在异常处理程序中执行插入。

现在,在任何人攻击我之前,我不建议您使用异常处理程序来控制代码中的执行流程,这些示例是理论上的,但希望您能理解..

【讨论】:

谢谢!您说这取决于“在程序中实现的实际功能(..)”。你能否详细说明一下。什么情况下最好在过程外处理异常?【参考方案2】:

您应该尝试从源头处理异常(即在引发异常的过程中)。这为您报告问题发生的位置提供了更大的范围,并且通常有更大的机会能够优雅地纠正问题,而不会将令人讨厌的 Oracle 错误消息向上传递给用户。

当然,如果您确实需要,您可以同时处理错误并重新引发错误,但正如 StevieG 回答的那样,您还可以引发用户定义的异常,这些异常通常更具应用程序特定性,对您的用户/其他 PL/SQL 代码更有帮助.

这里有一个关于自定义错误处理的 ASKTOM 讨论: http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:4684561825338

【讨论】:

【参考方案3】:

最好在程序内部处理异常。结果会很快。不仅如此,如果我们在其他一些函数中重用相同的过程,我们也不需要处理异常。我个人的观点,异常可以在程序里面自己处理是最好的一种。

【讨论】:

你能解释一下“结果会很快”吗?

以上是关于PL/SQL 过程中的异常处理的主要内容,如果未能解决你的问题,请参考以下文章

PL/SQL 中的异常处理和回滚

如何以不同的方式处理 PL/SQL 中的不同异常?

Oracle pl/sql 更新表的过程 - 异常处理

如何修改我的 PL/SQL 过程以进行异常处理?

Pl Sql 过程在使用 oracle 调度程序进行调度时处理异常

使用 pl/sql 过程记录错误和处理异常