处理来自 Oracle SQL Developer 中另一个过程中使用的函数的异常



我有这个功能:

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 指令 需要在处理错误的过程/函数中,而不是引发错误的过程/函数中。

相关内容

最新更新