Именованные системные исключения в PL/SQL Oracle
В Oracle для относительно небольшого количества исключений определены стандартные имена, задаваемые директивой компилятора EXCEPTION_INIT во встроенных пакетах. Самые важные и часто применяемые из них определены в пакете STANDARD. Так как это один из двух используемых по умолчанию пакетов PL/SQL, на определенные в нем исключения можно ссылаться без префикса с именем пакета. Например, если потребуется инициировать в программе исключение NO_DATA_FOUND, это можно сделать любой из следующих команд:
WHEN NO_DATA_FOUND THEN WHEN STANDARD.NO_DATA_FOUND THEN
Определения стандартных именованных исключений встречаются и в других встроенных пакетах — например, в пакете DBMS_LOB, предназначенном для работы с большими объектами. Пример одного такого определения из указанного пакета:
invalid_argval EXCEPTION; PRAGMA EXCEPTION_INIT(invalid_argval, -21560);
Поскольку пакет DBMS_LOB не используется по умолчанию, перед ссылкой на это исключение необходимо указать имя пакета:
WHEN DBMS_LOB.invalid_argval THEN...
Многие исключения, определенные в пакете STANDARD, перечислены в таблице ниже. Для каждого из них приводится номер ошибки Oracle, значение, возвращаемое при вызове SQLCODE (встроенная функция, которая возвращает текущий код ошибки), и краткое описание. Значение, возвращаемое SQLCODE, совпадает с кодом ошибки Oracle, с одним исключением: определяемый стандартом ANSI код ошибки NO_DATA_FOUND равен 100.
Имя исключения/ошибка Oracle/SQLCODE | Описание |
CURSOR_ALREADY_OPEN ORA-6511 SQLCODE = –6511 |
Попытка открытия курсора, который был открыт ранее. Перед повторным открытием курсор необходимо сначала закрыть |
DUP_VAL_ON_INDEX ORA-00001 SQLCODE = −1 |
Команда INSERT или UPDATE пытается сохранить повторяющиеся значения в столбцах, объявленных с ограничением UNIQUE |
INVALID_CURSOR ORA-01001 SQLCODE= −1001 | Ссылка на несуществующий курсор. Обычно ошибка встречается при попытке выборки данных из не открытого курсора или закрытия курсора до его открытия |
INVALID_NUMBER ORA-01722 SQLCODE = −1722 |
Выполняемая SQL-команда не может преобразовать символьную строку в число. Это исключение отличается от VALUE_ERROR тем, что оно инициируется только из SQL-команд |
LOGIN_DENIED ORA-01017 SQLCODE = −1017 |
Попытка программы подключиться к СУБД Oracle с неверным именем пользователя или паролем. Исключение обычно встречается при внедрении кода PL/SQL в язык 3GL |
NO_DATA_FOUND ORA-01403 SQLCODE= +100 | Исключение инициируется в трех случаях: (1) при выполнении инструкции SELECT INTO (неявный курсор), которая не возвращает ни одной записи; (2) при ссылке на неинициализированную запись локальной таблицы PL/SQL; (3) при попытке выполнить операцию чтения после достижения конца файла при использовании пакета UTL_FILE |
NOT_LOGGED ON ORA-01012 SQLCODE = −1012 |
Программа пытается обратиться к базе данных (обычно из инструкции DML) до подключения к СУБД Oracle |
PROGRAM_ERROR ORA-06501 SQLCODE = −6501 |
Внутренняя программная ошибка PL/SQL. В сообщении об ошибке обычно предлагается обратиться в службу поддержки Oracle |
STORAGE_ERROR ORA-06500 SQLCODE= −6500 | Программе PL/SQL не хватает памяти или память по какой-то причине повреждена |
TIMEOUT_ON_RESOURCE ORA-00051 SQLCODE = −51 |
Тайм-аут СУБД при ожидании ресурса |
TOO_MANY_ROWS ORA-01422 SQLCODE = −1422 |
Команда SELECT INTO возвращает несколько записей, хотя должна возвращать лишь одну (в таких случаях инструкция SELECT включается в явное определение курсора, а записи выбираются по одной) |
TRANSACTION_BACKED_OUT ORA-00061 SQLCODE = −61 |
Удаленная часть транзакции отменена либо при помощи явной инструкции ROLLBACK, либо в результате какого-то другого действия (например, неудачного выполнения команды SQL или DML в удаленной базе данных) |
VALUE_ERROR ORA-06502 SQLCODE = −6502 |
Ошибка связана с преобразованием, усечением или проверкой ограничений числовых или символьных данных. Это общее и очень распространенное исключение. Если подобная ошибка содержится в инструкции SQL или DML, то в блоке PL/SQL инициируется исключение INVALID_NUMBER |
ZERO_DIVIDE ORA-01476 SQLCODE = −1476 |
Попытка деления на ноль |
Рассмотрим пример использования этой таблицы исключений. Предположим, ваша программа инициирует необрабатываемое исключение для ошибки ORA-6511. Заглянув в таблицу, вы видите, что она связана с исключением CURSOR_ALREADY_OPEN. Найдите блок PL/SQL, в котором произошла ошибка, и добавьте в него обработчик исключения CURSOR_ALREADY_OPEN:
EXCEPTION WHEN CURSOR_ALREADY_OPEN THEN CLOSE my_cursor; END;
Конечно, еще лучше было бы проанализировать весь программный код и заранее определить, какие из стандартных исключений в нем могут инициироваться. В таком случае вы сможете решить, какие исключения следует обрабатывать конкретно, какие следует включить в конструкцию WHEN OTHERS, а какие оставить необработанными.
Метки: EXCEPTION, Oracle, Исключения.