我有一个相当简单的问题:是否可以在包级别进行异常处理?如果是的话,如何实施呢?
我的包中有程序和功能,如果是,我要说NO_DATA_FOUND
例外,我想在我的所有程序和函数中做同样的事情。
所以我的问题是:我可以写
WHEN NO_DATA_FOUND THEN
只需在我的所有过程/函数中对NO_DATA_FOUND
异常使用相同的行,或者我必须在每个过程/函数中编写该异常处理程序。
答案 0 :(得分:5)
不,您无法在程序包中的所有过程/函数中全局处理异常。
The exception handler documentation说:
异常处理程序处理引发的异常。异常处理程序出现在匿名块,子程序,触发器和包的异常处理部分中。
这听起来像你一样;但是'包裹'引用是指create package body
statement:
但该部分"初始化变量并执行任何其他一次性设置步骤",并且每次会话运行一次,此时首次调用包中的函数或过程。它的异常处理程序不会做任何其他事情。
如果你真的想要类似的行为,那么你可以把它放到它自己的(可能是私有的)过程中,并从每个过程/函数的异常处理程序中调用它。如果您正在尝试记录错误,那么可能会节省一些打字但可能会掩盖真正发生的事情。具体的异常处理可能会更简单,更好,即使这会导致一些重复。
答案 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;