Reputation: 1465
I have this function:
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;
There is a procedure that uses my function. The problem is that when my function raises the error 20001
, the procedure can not handle the exception; when I try to compile it, I get PLS-00201: identifier my_exception must be declared
.
If I run the procedure without treating this exception, it will still throw out the exception and error code, halting its execution. How can I treat my_exception
from that function?
Upvotes: 0
Views: 3871
Reputation: 14861
What your current code is doing: 1. A procedure calls TEST_FUNCTION. 2. TEST_FUNCTION raises my_exception. 3. TEST_FUNCTION traps the my_exception and replaces it with -20001 4. The calling procedure receives user defined exception -20001.
As I understand what your asking is: 1. A procedure calls TEST_FUNCTION. 2. TEST_FUNCTION raises user defined exception (my_exception) -20001. 3. The calling procedure should handle error.
To have the calling procedure handle you need to move declaration of my_exception and he pragma to the that procedure, remove exception block from TEST_FUNCTION and just raise he user defined error directly in the TEST_FUNCTION. Then in the calling procedure handle 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;
There are of course many other valid ways of laying out the code, but the main idea is that the exception declaration and the Pragma directive need to be in procedure/function that handles the error, NOT the one that raises the error.
Upvotes: 1
Reputation: 146239
You have declared my_exception
in the private namespace of your function. That means it is hidden from any other program unit.
This is one advantage of packages: anything we declare in a package spec is available to any other program in our schema (or other users if we have granted them execute privilege.
So you could do this:
CREATE OR REPLACE PACKAGE app_exceptions
AS
my_exception EXCEPTION;
PRAGMA EXCEPTION_INIT(my_exception, -20001);
end;
/
Now your function would look like this:
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;
If we want the calling program to handle the exception (and usually we do) it's fine to just propagate it.
Your calling procedure will look something like this:
....
l_n := TEST_FUNCTION ( l_whatever );
exception
when app_exceptions.my_exception then
-- handling code here
Upvotes: 3