我有这个功能:
CREATE OR REPLACE FUNCTION TEST_FUNCTION (p_test IN NUMBER) RETURN NUMBER
AS
my_exception EXCEPTION;
PRAGMA EXCEPTION_INIT(my_exception, -20001);
BEGIN
IF (p_test = 0) THEN
RAISE my_exception;
ELSE
RETURN 1;
END IF;
EXCEPTION
WHEN my_exception THEN
raise_application_error(-20001, 'p_test = 1');
RETURN 0;
END;
有一个使用我的函数的过程。问题是当我的函数引发错误20001
时,过程无法处理异常;当我尝试编译它时,我得到PLS-00201: identifier my_exception must be declared
.
如果我在不处理此异常的情况下运行该过程,它仍将抛出异常和错误代码,停止其执行。如何从该功能中治疗my_exception
?
您已在函数的私有命名空间中声明了my_exception
。这意味着它对任何其他程序单元都是隐藏的。
这是包的一个优点:我们在包规范中声明的任何内容都可用于模式中的任何其他程序(或者其他用户,如果我们授予他们执行权限。
所以你可以这样做:
CREATE OR REPLACE PACKAGE app_exceptions
AS
my_exception EXCEPTION;
PRAGMA EXCEPTION_INIT(my_exception, -20001);
end;
/
现在你的函数看起来像这样:
CREATE OR REPLACE FUNCTION TEST_FUNCTION (p_test IN NUMBER) RETURN NUMBER
AS
BEGIN
IF (p_test = 0) THEN
RAISE app_exceptions.my_exception;
ELSE
RETURN 1;
END IF;
END;
如果我们希望调用程序处理异常(通常我们这样做),那么传播它就可以了。
您的调用过程将如下所示:
....
l_n := TEST_FUNCTION ( l_whatever );
exception
when app_exceptions.my_exception then
-- handling code here
你当前的代码在做什么: 1. 过程调用TEST_FUNCTION。 2.TEST_FUNCTION提高my_exception。 3. TEST_FUNCTION捕获my_exception并将其替换为 -20001 4. 调用过程接收用户定义的异常 -20001。
据我了解您的要求是什么: 1. 过程调用TEST_FUNCTION。 2. TEST_FUNCTION引发用户定义的异常 (my_exception) -20001。 3. 调用过程应处理错误。
要使调用过程句柄,您需要将my_exception和杂注的声明移动到该过程,从TEST_FUNCTION中删除异常块,然后直接在TEST_FUNCTION中引发用户定义的错误。然后在调用过程中处理my_exception。
所以:
create or replace
function test_function (p_test in number)
return number
as
begin
if (p_test = 0) then
raise_application_error(-20001,'p_test = 0');
end if;
return 1;
end test_function;
create or replace
procedure caller_for_test_function
is
my_exception EXCEPTION;
PRAGMA EXCEPTION_INIT(my_exception, -20001);
x number;
begin
...
x := text_function(0);
...
exception
when my_exception then
<Handle my_exception here>;
end caller_for_test_function;
当然还有许多其他有效的代码布局方法,但主要思想是异常声明和 Pragma 指令 需要在处理错误的过程/函数中,而不是引发错误的过程/函数中。