【发布时间】:2016-05-17 17:18:44
【问题描述】:
我有一个相当简单的问题:是否可以在包级别进行异常处理?如果是,如何实现?
我的包中有过程和函数,如果出现NO_DATA_FOUND 异常,我想在我的所有过程和函数中做同样的事情。
所以我的问题是:我可以写吗
WHEN NO_DATA_FOUND THEN
只需一次并在我的所有过程/函数中对NO_DATA_FOUND 异常使用相同的行,或者我是否必须在每个过程/函数中编写该异常处理程序。
【问题讨论】:
我有一个相当简单的问题:是否可以在包级别进行异常处理?如果是,如何实现?
我的包中有过程和函数,如果出现NO_DATA_FOUND 异常,我想在我的所有过程和函数中做同样的事情。
所以我的问题是:我可以写吗
WHEN NO_DATA_FOUND THEN
只需一次并在我的所有过程/函数中对NO_DATA_FOUND 异常使用相同的行,或者我是否必须在每个过程/函数中编写该异常处理程序。
【问题讨论】:
不,您不能在包中的所有过程/函数中全局处理异常。
The exception handler documentation 说:
异常处理程序处理引发的异常。异常处理程序出现在匿名块、子程序、触发器和包的异常处理部分。
这听起来像你可以;但是那里的“包”参考是指create package body statement的初始化部分:
但是该部分“初始化变量并执行任何其他一次性设置步骤”,并且在第一次调用包中的函数或过程时每个会话运行一次。它的异常处理程序不做任何其他事情。
如果你真的想要类似的行为,那么你可以将它放入它自己的(可能是私有的)过程中,并从每个过程/函数的异常处理程序中调用它。例如,如果您尝试记录错误,这可能会节省一些打字时间,但可能会掩盖真正发生的事情。有特定的异常处理可能会更简单更好,即使这会导致一些重复。
【讨论】:
不,这是不可能的。我希望这不在语言中,因为它与异常处理程序的正确和预期用途不一致。
我应用的一般经验法则是:“如果您没有针对异常执行的具体和有用的操作,请不要捕获它”。
如果NO_DATA_FOUND 在给定情况下是预期的并且可以,并且您可以忽略它和/或假设数据的默认值,那么您需要捕获并处理它(并且包级处理程序不会' t 帮助,因为您的处理将取决于情况)。在所有其他情况下,您不想捕获NO_DATA_FOUND - 它代表一个真正的例外:不应该发生的事情,超出您的设计假设的事情。让那些传播到顶层,他们可以记录它们和/或将它们报告给客户端。
但如果你解释了你希望包级异常处理程序做什么,也许你会得到更好的答案。
【讨论】:
包不是可执行对象,因此它无法处理包中的过程和函数的异常。你需要处理它产生的异常。
每次抛出特定异常时,您似乎不太可能真的想做完全相同的事情。通常,您希望异常处理程序尽可能靠近生成错误的代码,以便尽可能多地使用上下文。通常,这意味着在单个过程中有多个异常处理程序,
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;
【讨论】: