我有这个功能:
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
?
答案 0 :(得分:2)
您已在函数的私有命名空间中声明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 :(得分:1)
您当前的代码正在做什么: 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的声明并将pragma移动到该过程,从TEST_FUNCTION中删除异常块,并直接在TEST_FUNCTION中引发用户定义的错误。然后在调用过程中处理my_exception。
SO:
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指令 需要在处理错误的过程/函数中,而不是引发错误的过程/函数。