我对在oracle存储过程中处理异常有一些疑问,特别是关于sqlerrm的使用。让我解释一下。
根据oracle官方文档,sqlerrm是一个函数:
“..返回与最近引发的错误异常相关的错误消息。此函数只能在代码的异常处理部分中使用。”
oracle异常语法是:
EXCEPTION
WHEN exception_name1 THEN
[statements]
WHEN exception_name_n THEN
[statements]
WHEN OTHERS THEN
[statements] --Here use SQLERRM and do a trace
END;
通常,在发生不受控制的异常时使用SQLERRM。
现在,当您将一些暴露于异常的函数调用到存储过程中时,异常处理会发生什么?
让我用一个例子来解释:
--Create a packague
CREATE OR REPLACE PACKAGE BODY MY_PACKAGE AS
FUNCTION F1() RETURN NUMBER IS
BEGIN
--do querys and return a value
END F1;
FUNCTION F2() RETURN NUMBER IS
BEGIN
--do querys and return a value
END F2;
FUNCTION F3() RETURN NUMBER IS
BEGIN
--do querys and return a value
END F3;
PROCEDURE MY_PROCEDURE(v_mssg_err OUT VARCHAR2) IS
v1 NUMBER; v2 NUMBER; v3 VARCHAR2(10);
BEGIN
v1 := FUNCTION1();
v2 := FUNCTION2();
v3 := FUNCTION3();
v_mssg_err := 'OK';
EXCEPTION WHEN OTHERS THEN
--If an error happens in F1(),F2() or F3()
v_mssg_err := sqlerrm;
-- I think this is a correct way to handle exceptions
END MY_PROCEDURE;
END MY_PACKAGE;
我认为SQlERRM返回F1(),F2()或F3()中出现的错误消息。
但是,我收到了一个包,其中正在处理包中声明的每个函数的异常。这样。
FUNCTION F4() RETURN VARCHAR2 IS
response VARCHAR2(1000); --511 is the max length possible for SQLERRM
BEGIN
--do querys and return a string value
RETURN response;
EXCEPTION WHEN OTHERS THEN
response := TO_CHAR(-1)||sqlerrm;
END F4;
我不确定这是处理异常的有效方法。因为对于调用该函数的每个存储过程,它是必要的拆分并检查值返回。
回到我的问题
调用多个函数的存储过程中的范围和正确的异常处理是什么?非常感谢你的帮助!
来源:
答案 0 :(得分:0)
这取决于错误的类型以及您希望如何管理它。您的异常将被最近的封闭块(或块本身)捕获,该块具有该异常的异常处理程序。
如果要将异常捕获到F1()中,则意味着您要从那里处理异常。然后,您的主程序将能够继续执行F2,F3等。如果从主程序中捕获F1()的异常,则执行将在那里停止,因此它将无法调用其他函数。
另请注意,您需要将return语句放入函数的异常处理中,否则在执行时会抛出异常(ORA-06503)。