Обработка ошибок
Ввод новых ограничений в уже созданную таблицу
Особенно полезен оператор GET DIAGNOSTICS для определения нарушаемых ограничений при изменении исходных таблиц. Например, в таблицу с помощью оператора ALTER TABLE вводят ограничения, которых не было при написании программы:
ALTER TABLE EMPLOYEE ADD CONSTRAINT SalLimit CHECK(Salary < 200000);
Теперь, когда вы вставите данные в таблицу EMPLOYEE или обновите в ней столбец Salary и значение в этом столбце превысит 200000, значение SQLSTATE станет равно '23000'. В таких случаях можно запрограммировать вывод каких-либо полезных сообщений. Например, такого рода: "Неправильное выполнение оператора INSERT: нарушение ограничения SalLimit".
Что означает информация, возвращаемая параметром SQLSTATE
В элементах CONNECTTON_NAME и ENVIRONMENTJVAME хранятся названия соединения и той среды, с которой было установлено соединение во время выполнения оператора SQL.
Если информация из параметра SQLSTATE относится к работе с таблицей, то эту таблицу определяют элементы CATALOG_NAME, SCHEMA_NAME и TABLE_NAME. Если появление ошибки как-то связано со столбцом таблицы, его имя помещается в элемент COLUMN_NAME. Если нештатная ситуация имеет отношение к курсору, его имя будет находиться в элементе CURSOR_NAME.
Иногда СУБД, чтобы объяснить ситуацию, создает строку текста на каком-либо языке, например английском. Такого рода информация содержится в элементе MESSAGE_TEXT. Его содержимое определяется не стандартом SQL.2003, а реализацией. Если в элементе MESSAGEJTEXT имеется сообщение, его длина в символах записывается в элемент MESSAGE_LENGTH, а длина в октетах – в элемент MESSAGE_OCTET_LENGTH. У сообщения, состоящего из обычных ASCII-символов, значения MESSAGE_LENGTH и MESSAGE_OCTET_LENGTH равны между собой. А если сообщение составлено на китайском, японском или любом другом языке, в котором для выражения символа требуется больше одного октета, то значения MESSAGE_LENGTH и MESSAGE_OCTET_LENGTH будут разными.
Чтобы получить диагностическую информацию из области заголовка, воспользуйтесь выражением:
GET DIAGNOSTICS переменная1 = элемент1 [, переменная2 = елемент2]…;
Где переменная_n – это параметр или базовая переменная; элемент_n – любое из следующих ключевых слов: NUMBER, MORE, COMMAND_FUNCTION, DYNAMIC_FUNCTION или ROW_COUNT.
А чтобы получить диагностическую информацию из информационной области, используют следующий синтаксис:
GET DIAGNOSTICS EXCEPTION номер-состояния переменная1 = элемент1 [, переменная2 = элемент2]…;
Где переменная_n – это параметр или базовая переменная; элемент_n – любое из семнадцати ключевых слов элементов информационной области.
Эти ключевые слова приведены в табл. 20.2. И наконец, номер состояния – это значение элемента CONDITION_NUMBER информационной области.
Обработка исключений
Если параметр состояния SQLSTATE не равен 00000, 00001 или 00002, значит, возникла исключительная ситуация, которую, возможно, нужно будет обработать.
- Обработка может состоять в возвращении управления родительской процедуре, в которой была вызвана подпроцедура – источник исключения.
- Второй способ обработки состоит в использовании предложения WHENEVER для перехода на нужную процедуру обработки или выполнения какого-либо другого действия.
- Третий способ заключается в том, чтобы обрабатывать ситуацию прямо на месте, используя для этого составной оператор SQL. Составным называется такой SQL-оператор, который состоит из более простых операторов SQL, находящихся между ключевыми словами BEGIN (начало) и END (конец).
Ниже приведен пример составного оператора, выполняющего обработку исключительных ситуаций.
BEGIN DECLARE ValueOutOfRange EXCEPTION FOR SQLSTATE '73003'; INSERT INTO FOODS (Calories) VALUES (:cal) SIGNAL ValueOutOfRange; MESSAGE 'Обрабатывается новое значение количества калорий' EXCEPTION WHEN ValueOutOfRange THEN MESSAGE 'Обработка ошибки выхода количества калорий за допустимый диапазон'; WHEN OTHERS THEN RESIGNAL; END
С помощью одного или нескольких объявлений можно задать имена для всех возможных значений параметра SQLSTATE. Одним из операторов, которые могут вызвать исключительную ситуацию, является INSERT. Если значение:cal превысит максимальное значение элемента данных типа SMALLINT, параметру SQLSTATE будет присвоено значение '73003'. Сигнал о возникновении исключительной ситуации подает оператор SIGNAL (сигнализировать). Этот оператор очищает область диагностики, а также присваивает полю RETURNED_SQLSTATE этой области значение параметра SQLSTATE. Если исключения не было, выполняется обычная последовательность операторов, роль которой в нашем примере играет MESSAGE 'Обрабатывается новое значение количества калорий1. Если же это исключение все же имело место, то обычная последовательность пропускается и выполняется оператор EXCEPTION.
Как только возникает исключение ValueOutOfRange (значение вне диапазона), выполняется последовательность операторов, представленных в нашем примере одним – MESSAGE 'Обработка ошибки выхода количества калорий за допустимый диапазон'. Когда возникнет какое-либо другое исключение, выполняется оператор RESIGNAL (сигнализировать повторно). Он просто передает управление вызывающей родительской процедуре. В этой процедуре, возможно, есть дополнительный код обработки ошибок, с помощью которого можно обрабатывать исключительные ситуации, не связанные с выходом за пределы диапазона.