I trying to handle exception if no rows found. In result I see an following error: PL/SQL: unhandled user-defined exception. A user-defined exception was raised by PL/SQL code, but not handled.
What I doing wrong?
DECLARE
my_exception EXCEPTION;
result1 VARCHAR2(50);
result2 NUMBER;
BEGIN
SELECT brand, year INTO result1, result2 FROM cars WHERE car_id=200;
EXCEPTION
WHEN NO_DATA_FOUND THEN
RAISE my_exception; WHEN my_exception THEN
DBMS_OUTPUT.PUT_LINE('Exception has been thrown');
END;
CodePudding user response:
You are successfully trapping the NO_DATA_FOUND exception, but within that exception handler you are then raising a new user-defined exception of your own (RAISE my_exception).
When you raise from an exception handler like this, it falls back to the parent block and looks for an exception handler there... but you have no parent block, and so on until it reaches the outermost block. If it isn't caught, it will finally throw the "unhandled user-defined exception" to the client.
If you want to continue execution and do nothing but emit that dbms_output message, then remove the "RAISE my_exception" line and everything to do with that exception. Just put the dbms_output in the handler for NO_DATA_FOUND.
If however you really do want to use a user defined exception, then nest the entire thing in a wrapping parent block and handle it there:
DECLARE
my_exception exception;
BEGIN
DECLARE
result1 VARCHAR2(50);
result2 NUMBER;
BEGIN
SELECT brand, year INTO result1, result2 FROM cars WHERE car_id=200;
EXCEPTION
WHEN NO_DATA_FOUND THEN
RAISE my_exception;
END;
EXCEPTION
WHEN my_exception THEN
dbms_output.put_line("my_exception raised")
END;
CodePudding user response:
The exception handler in the outer block has already been called when the NO_DATA_FOUND
exception was raised. If you raise another exception inside the exception handling block then it will not be caught at the same level; instead you either need to:
- Wrap the
RAISE
statement inside its own PL/SQL anonymous block and catch the exception inside the exception handler of that block:
DECLARE
my_exception EXCEPTION;
result1 VARCHAR2(50);
result2 NUMBER;
BEGIN
SELECT brand, year INTO result1, result2 FROM cars WHERE car_id=200;
EXCEPTION
WHEN NO_DATA_FOUND THEN
BEGIN
RAISE my_exception;
EXCEPTION
WHEN my_exception THEN
DBMS_OUTPUT.PUT_LINE('Exception has been thrown');
END;
END;
/
- Wrap the block raising the exception in an outer block and catch the exception there:
DECLARE
my_exception EXCEPTION;
BEGIN
DECLARE
result1 VARCHAR2(50);
result2 NUMBER;
BEGIN
SELECT brand, year INTO result1, result2 FROM cars WHERE car_id=200;
EXCEPTION
WHEN NO_DATA_FOUND THEN
RAISE my_exception;
END;
EXCEPTION
WHEN my_exception THEN
DBMS_OUTPUT.PUT_LINE('Exception has been thrown');
END;
/
Both of which output:
Exception has been thrown