程序中的PL / SQL异常处理

时间:2011-09-09 10:52:35

标签: stored-procedures exception-handling plsql

这是一个关于最佳实践的问题。我有一个类似于这个的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块围绕每个调用主体中的程序?

3 个答案:

答案 0 :(得分:6)

就个人而言,我会在他们被抛出的程序中抓住他们。这意味着您可以更好地控制外部处理方式。例如,您可以将其作为用户定义的异常再次抛出,您可以使用更多有关确切错误的信息进行修饰。

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

在程序之外比

更具描述性
'no data found'

但这实际上取决于:

  1. 调用应用程序的错误报告要求
  2. 在程序中执行“实际操作”的实际功能
  3. 例如,假设您希望运行过程2,即使过程1中的select没有找到行。您需要在过程1中捕获异常并忽略它。如果你没有,那么它将被抛出到过程2中的异常处理程序。

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

    现在,在有人跳过我之前,我不建议您使用异常处理程序来控制代码中的执行流程,这些示例是理论上的,但希望您能得到这个想法。

答案 1 :(得分:3)

您应该尝试在源处处理异常(即在引发它们的过程中)。这为您提供了报告问题发生位置的更大空间,并且通常可以更好地优雅地纠正问题,而无需将堆栈中令人讨厌的Oracle错误消息传递给用户。

当然,如果你真的需要,你可以处理错误并重新提升它,但是如StevieG所说,你也可以引发用户定义的异常,这些异常通常更具针对性,对你的用户/其他PL / SQL代码更有帮助

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

答案 2 :(得分:1)

最好在程序中处理异常。它会很快。不仅如果我们在其他一些函数中重用相同的过程,我们也不需要处理异常。我的观点是,异常可以处理程序内部本身是最好的。