При выполнении кода PL/SQL могут возникнуть ошибки, которые вызовут прекращение выполнения блока PL/SQL. Такие ошибки создают исключения, которые можно перехватывать и обрабатывать с помощью обработчика исключений.
Исключение – переменная PL/SQL, возбуждаемая во время выполнения блока и прекращающая выполнение действий в теле блока. Если Ваш блок PL/SQL содержит секцию обработки исключений, Вы можете определить действия, которые должны быть выполнены для того или иного исключения перед завершением блока.
Исключение возбуждается автоматически сервером Oracle в случае возникновения ошибки Oracle (TOO_MANY_ROWS, NO_DATA_FOUND). Однако Вы можете определить свое собственное исключение в декларативной секции блока PL/SQL и, затем, явно возбудить его в исполняемой секции блока.
Если в исполняемой секции блока возбуждается исключение, управление передается секции обработки исключений (секции EXCEPTION). В том случае, если исключение будет успешно обработано, блок PL/SQL завершится без ошибок. Если же обработчика для этого исключения нет, выполнение блока PL/SQL прекратится в аварийном порядке.
Имеется три типа исключений:
Исключение |
Описание |
Обработка |
Предопределенное, возбуждаемое сервером Oracle |
Типичная ошибка, возникающая при выполнении блока PL/SQL (примерно 20) |
Описывать не надо, возбуждать не надо |
Неопределенное, возбуждаемое сервером Oracle |
Любая другая стандартная ошибка сервера Oracle |
Необходимо описывать в декларативной секции, возбуждать не надо |
Пользовательское |
Исключение, определенное пользователем |
Необходимо описать в декларативной секции и возбудить явно в исполняемой секции |
Перехват исключений осуществляется в секции обработки исключений блока PL/SQL.
WHEN исключение_1 [OR исключение_2 ...] THEN
операторы;
WHEN исключение_3 [OR исключение_4 ...] THEN
операторы;
...
[WHEN OTHERS THEN
операторы;]
исключение – имя предопределенного исключения или исключения, описанного в декларативной секции
WHEN OTHERS – определяет действия по обработке всех исключений, обработка для которых не задана явно
Секция обработки исключений начинается ключевым словом EXCEPTION. В секцию обработки исключений можно включить несколько обработчиков исключений, каждый из которых выполняет собственную группу операторов. Если в исполняемой секции блока PL/SQL возбуждается исключение, управление передается в секцию обработки исключений тому обработчику, который предназначен для обработки именно этого исключения. После выполнения действий, заданных в этом обработчике, выполнение блока прекращается без ошибок.
Вы можете определить действия, которые должны быть выполнены в случае возбуждения любых исключений, обработчик которых не определен явно. Для этого используется предложение WHEN OTHERS. Предложение WHEN OTHERS может быть только одно и помещается после всех остальных обработчиков исключений.
Перехват предопределенных ошибок сервера Oracle осуществляется путем ссылки на стандартное имя исключения в секции обработки исключений.
Имя исключения |
Номер ошибки |
Описание |
CURSOR_ALREADY_OPEN |
ORA-06511 |
Попытка открыть курсор, который уже открыт |
DUP_VAL_ON_INDEX |
ORA-00001 |
Попытка сохранить дублирующее значение в колонке таблицы базы данных при уникальном ограничении, заданном для этой колонки |
INVALID_CURSOR |
ORA-01001 |
Попытка выполнить неразрешенную операцию с курсором (закрытие неоткрытого курсора) |
INVALID_NUMBER |
ORA-01722 |
Попытка конвертировать символьное значение в численное в утверждении SQL, если символьное значение не представляет собой символьное представление числа |
LOGIN_DENIED |
ORA-01017 |
Попытка соединиться с базой данных с неправильным именем пользователя и/или паролем |
NO_DATA_FOUND |
ORA-01403 |
Утверждение SELECT INTO не вернуло ни одной строки |
NOT_LOGGED_ON |
ORA-01012 |
Попытка обратиться к базе данных, не соединившись с ней |
PROGRAM_ERROR |
ORA-06501 |
Внутренняя ошибка PL/SQL |
STORAGE_ERROR |
ORA-06500 |
Недостаточно памяти |
SYS_INVALID_ROWID |
ORA-01410 |
Попытка конвертировать символьное значение в ROWID, если символьное значение не представляет собой корректное символьное представление ROWID |
TIMEOUT_ON_RESOURCE |
ORA-00051 |
Время ожидания ресурса истекло |
TOO_MANY_ROWS |
ORA-01422 |
Утверждение SELECT INTO вернуло более одной строки |
VALUE_ERROR |
ORA-06502 |
Ошибка вычислений, преобразования типов, нарушение размерности |
ZERO_DIVIDE |
ORA-01476 |
Попытка деления на ноль |
Рассмотрим пример. Пусть имеется командный файл except.sql для вычисления заработной платы сотрудника с определенной должностью. В этом случае необходимо предусмотреть обработку ситуаций, когда сотрудников с такой должностью не существует или несколько сотрудников имеют такую должность.
DECLARE
v_sal emp.sal%TYPE;
BEGIN
SELECT sal INTO v_sal FROM emp WHERE LOWER(job)=LOWER(:v_job);
DBMS_OUTPUT.put_line('Salary of ' || :v_job || ' is ' || TO_CHAR(v_sal));
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.put_line(:v_job || ' is not a title of employees');
WHEN TOO_MANY_ROWS THEN
DBMS_OUTPUT.put_line(:v_job || ' is a title of many employees');
WHEN OTHERS THEN
DBMS_OUTPUT.put_line('Other error occurred');
END;
/
Теперь рассмотрим различные варианты, присваивая разные значения хост-переменной v_job.
SQL> VARIABLE v_job VARCHAR2(20)
SQL> EXECUTE :v_job := 'President'
PL/SQL procedure successfully completed.
SQL> @d:\users\except
Salary of President is 5000
PL/SQL procedure successfully completed.
SQL> EXECUTE :v_job := 'Clerk'
PL/SQL procedure successfully completed.
SQL> @d:\users\except
Clerk is a title of many employees
PL/SQL procedure successfully completed.
SQL> EXECUTE :v_job := 'Engineer'
PL/SQL procedure successfully completed.
SQL> @d:\users\except
Engineer is not a title of employees
PL/SQL procedure successfully completed.
Если Вы хотите обработать стандартную ошибку сервера Oracle, которая не является предопределенной ошибкой, необходимо сначала объявить это исключение в декларативной секции, связать его со стандартным номером ошибки и сослаться на исключение в секции обработки исключений.
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.