Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Programming PL SQL.doc
Скачиваний:
3
Добавлен:
01.07.2025
Размер:
5.06 Mб
Скачать

6.4.2 Unhandled Exceptions

If an exception is raised in your program and it is not handled by an exception section in either the current or enclosing PL/SQL blocks, that exception is unhandled. PL/SQL returns the error that raised the unhandled exception all the way back to the application environment from which PL/SQL was run. That environment (a tool like SQL*Plus, Oracle Forms, or a Java program) then takes an action appropriate to the situation; in the case of SQL*Plus, a ROLLBACK of any DML changes from within that top-level block's logic is automatically performed.

One key decision to make about your application architecture is whether you want to allow unhandled exceptions to occur at all. They are handled differently by different front ends, and in some cases none too gracefully. If your PL/SQL programs are being called from a non-PL/SQL environment, you may want to design your outermost blocks or programs to do the following:

  • Trap any exception that might have propagated out to that point.

  • Log the error so that a developer can analyze what might be the cause of the problem.

  • Pass back a status code, description, and any other information needed by the host environment to make a determination about an appropriate action to take.

6.4.3 Using sqlcode and sqlerrm in Handler Clauses

You can use the WHEN OTHERS clause in the exception section to trap any otherwise unhandled exceptions. Once inside the exception handler, however, you will often want to know which error occurred. You can use the SQLCODE function to obtain this information. SQLCODE returns the current error number (0 indicates that there is no error on the error stack); SQLERRM returns the error message for the current error or whatever error number you pass to it.

Combined with WHEN OTHERS, SQLCODE provides a way for you to handle different, specific exceptions without having to use the EXCEPTION_INIT pragma. In the next example, I trap two parent-child exceptions, -2292 and -2291, and then take an action appropriate to each situation:

PROCEDURE delete_company (company_id_in IN NUMBER)

IS

BEGIN

DELETE FROM company WHERE company_id = company_id_in;

EXCEPTION

WHEN OTHERS

THEN

/*

|| Anonymous block inside the exception handler lets me declare

|| local variables to hold the error code information.

*/

DECLARE

error_code NUMBER := SQLCODE;

error_msg VARCHAR2 (512) := SQLERRM; -- Maximum length of SQLERRM string.

BEGIN

IF error_code = -2292

THEN

/* Child records found. Delete those too! */

DELETE FROM employee WHERE company_id = company_id_in;

/* Now delete parent again. */

DELETE FROM company WHERE company_id = company_id_in;

ELSIF error_code = -2291

THEN

/* Parent key not found. */

DBMS_OUTPUT.PUT_LINE (' Invalid company ID: '||TO_CHAR (company_id_in));

ELSE

/* This is like a WHEN OTHERS inside a WHEN OTHERS! */

DBMS_OUTPUT.PUT_LINE (' Error deleting company, error: '||error_msg);

END IF;

END; -- End of anonymous block.

END delete_company;

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]