First, the TOO_MANY_ROWS exception will not catch the case where your select statements return multiple rows. TOO_MANY_ROWS exception for ORA-01422 when issuing a SELECT .. INTO statement that returns more than one row. The exception you will encounter in your case is ORA-01427. A single row subquery returns more than one row.
If you want to handle this specific error in your procedure, use the EXCEPTION_INIT pragma to associate the exception name with the error:
too_many_values EXCEPTION; PRAGMA EXCEPTION_INIT(too_many_values, -1427);
You can then reference this name in your exception handler:
EXCEPTION WHEN TOO_MANY_VALUES THEN {perform your handler here}
What you put in the handler depends on what your procedure does. Many times you need to return the caller code of some code / message:
PROCEDURE my_proc(p_one VARCHAR2, p_err OUT VARCHAR2) IS too_many_values EXCEPTION; PRAGMA EXCEPTION_INIT(too_many_values, -1427); BEGIN ... EXCEPTION WHEN TOO_MANY_VALUES THEN p_err := 'More than one value available to assign in the update'; RAISE;
Another approach is to skip specific exception handlers and return common oracle messages in the WHEN OTHERS handler:
EXCEPTION WHEN OTHERS THEN p_err := SQLERRM; END;
The advantage with the first approach is that you can customize your messages so that they are more convenient for end users when the result of the process is directly transmitted to the user. An advantage of the latter approach is less coding. Error handling is an important and often abbreviated aspect of any application.
The documentation from Oracle is here .
EDIT:
If this is a package and you want to avoid passing a long chain of errors using a series of procedure calls, you can declare an error variable with the scope of the package, set it when an error occurs, and FOLLOW the error again.
PACKAGE BODY my_pkg is g_err VARCHAR2(256); PROCEDURE procx(... , p_err OUT VARCHAR2) IS... ... proc_y(p1); EXCEPTION WHEN OTHERS THEN p_err := NVL(g_err, SQLERRM); END; PROCEDURE proc_y(p1 VARCHAR2) IS ... proc_z(p2); END; PROCEDURE proc_z(p2 VARCHAR2) IS too_many_values EXCEPTION; PRAGMA EXCEPTION_INIT(too_many_values, -1427); BEGIN .... EXCEPTION WHEN TOO_MANY_VALUES THEN g_err := 'More than one value available to assign in the update'; RAISE;
When an exception occurs in proc_z, it is processed and then raised again. It is distributed back through proc_y (there is no handler there), and then returned to the user in proc_x. Errors not set in the global g_err receive a generic Oracle error message. This avoids passing the initial error parameter in the entire packet.