PL / SQL包级异常处理

时间:2016-05-17 17:18:44

标签: sql oracle plsql

我有一个相当简单的问题:是否可以在包级别进行异常处理?如果是的话,如何实施呢?

我的包中有程序和功能,如果是,我要说NO_DATA_FOUND例外,我想在我的所有程序和函数中做同样的事情。

所以我的问题是:我可以写

WHEN NO_DATA_FOUND THEN

只需在我的所有过程/函数中对NO_DATA_FOUND异常使用相同的行,或者我必须在每个过程/函数中编写该异常处理程序。

3 个答案:

答案 0 :(得分:5)

不,您无法在程序包中的所有过程/函数中全局处理异常。

The exception handler documentation说:

  

异常处理程序处理引发的异常。异常处理程序出现在匿名块,子程序,触发器和包的异常处理部分中。

这听起来像你一样;但是'包裹'引用是指create package body statement

的初始化部分

enter image description here

但该部分"初始化变量并执行任何其他一次性设置步骤",并且每次会话运行一次,此时首次调用包中的函数或过程。它的异常处理程序不会做任何其他事情。

如果你真的想要类似的行为,那么你可以把它放到它自己的(可能是私有的)过程中,并从每个过程/函数的异常处理程序中调用它。如果您正在尝试记录错误,那么可能会节省一些打字但可能会掩盖真正发生的事情。具体的异常处理可能会更简单,更好,即使这会导致一些重复。

答案 1 :(得分:4)

不,这是不可能的。我希望那不是在语言中,因为它与异常处理程序的正确和有意使用不一致。

我申请的一般经验法则是:“如果你没有具体和有帮助的事情来回应异常,就不要抓住它。”

如果预期NO_DATA_FOUND并且在给定情况下确定并且您可以忽略它和/或假设数据的默认值,那么您需要捕获并处理它(以及包级处理程序)没有用,因为你的处理将取决于情况。在所有其他情况下,您不希望捕获NO_DATA_FOUND - 它代表一个真正的例外:不应该发生的事情,超出您的设计假设。让那些传播到顶级,可以记录它们和/或将它们报告给客户端。

但是如果你解释了你想要包级别的异常处理程序做什么,也许你会得到更好的答案。

答案 2 :(得分:4)

包不是可执行对象,因此它无法处理包中的过程和函数的异常。您需要处理生成它的异常。

每次抛出特定异常时,你真的想要做同样的事情似乎有点不太可能。通常,您希望异常处理程序尽可能接近生成错误的代码,以便具有最大可能的上下文量。通常,这意味着在一个过程中有多个异常处理程序,

PROCEDURE p1 
AS
  ...
BEGIN
  BEGIN
    SELECT col1
      INTO l_var1
      FROM some_table
     WHERE <<something>>
  EXCEPTION
    WHEN no_data_found
    THEN
      l_var1 := null;
  END;

  <<do something>>

  BEGIN
    SELECT col2
      INTO l_var2
      FROM some_table2
     WHERE <<something>>
  EXCEPTION
    WHEN no_data_found
    THEN
      raise_application_error( -20001, 'Error, cannot find a row in some_table2' );
  END;

  ...
END;