Пользовательские исключительные ситуации
описываются в раз-
деле DECLARE, устанавливаются в выполняемом разделе, а обрабаты-
ваются в разделе EXCEPTION. Описание пользовательской исключи-
тельной ситуации выполняется заданием имени исключения и фразы
EXCEPTION. Чтобы сгенерировать исключительную ситуацию и пере-
дать управление обработчику пользовательской исключительной ситуа-
ции в случае обнаружения ошибки, используется оператор
RAISE имя_пользовательского_исключения
Для перехвата исключительной ситуации любого типа в раздел
EXCEPTION должна быть включена фраза
WHEN имя_исключения THEN текст_обработчика_исключения;
Тогда при возникновении соответствующей ошибки, вместо прекраще-
ния исполнения программы и выдачи типового сообщения об ошибке,
будет выполняться созданный пользователем вариант обработки исклю-
чения. Если необходимо, чтобы две или более исключительные ситуации
обрабатывались одинаково, то они должны быть записаны в одном опе-
раторе WHEN, разделенные ключевым словом OR. Для перехвата всех
неописанных исключительных ситуаций используется специальный об-
работчик OTHERS, который записывается последним в разделе
EXCEPTION.
Генерация исключительной ситуации с выдачей соответствующего
сообщения в рабочую среду в случае обнаружения ошибки может быть
выполнена с помощью следующего оператора:
RAISE_APPLICATION_ERROR (errnum, errtext);
где errnum – код ошибки, выбираемый в диапазоне –20000 .. –20999;
errtext – поясняющая символьная строка длиной до 512 байт.
При возникновении исключительной ситуации и отсутствии соответ-
ствующего обработчика в данном блоке система пытается найти такой
обработчик в блоках, охватывающих этот блок. При отсутствии обработ-
чика система вернет ошибку «необработанное исключение».
160
П р и м е р ы
Создать программу, которая осуществляет в таблице BOOKS повы-
шение цен на книги жанра «Фантастика». При этом при стоимости книги
менее 2000 руб., цена увеличивается на 20 %, а при стоимости больше
или равной 2000 руб. – на 10 %.
Данная задача реализуется с помощью явно объявленного пользова-
телем курсора. При этом в первых двух вариантах показываются воз-
можности использования обычного курсора и курсора с параметром.
Приведенное решение демонстрирует два варианта обработки явно объ-
явленного курсора: явную и неявную формы. В явной форме обработки
по завершении просмотра строк активного набора осуществляется выход
из цикла обработки. При этом используется курсорный атрибут
%NOTFOUND. В неявной форме обработки курсора используется конст-
рукция цикл FOR с курсором. Модифицированное значение цены запи-
сывается обратно в таблицу BOOKS с использованием конструкции
WHERE CURRENT OF, при этом системе с помощью конструкции FOR
UPDATE OF PRICE указывается, что будет осуществляться обновление
значений столбца PRICE таблицы BOOKS. В программе неявным спосо-
бом объявлены переменная типа запись ZAP и скалярная переменная
NEW_ PRICE.
а) Использование обычного курсора:
DECLARE
CURSOR KUR IS --явное объявление курсора KUR
SELECT CODE_BOOK, PRICE FROM BOOKS
WHERE GENRE = 'Фантастика' FOR UPDATE OF PRICE;
ZAP KUR%ROWTYPE; --объявление переменной-записи
NEW_PRICE BOOKS.PRICE%TYPE; --объявление переменной
BEGIN
OPEN KUR; --явное открытие курсора
LOOP
FETCH KUR INTO ZAP; --выборка текущей записи
EXIT WHEN KUR%NOTFOUND; --выход из цикла
IF ZAP.PRICE < 2000 THEN --изменение цены
NEW_PRICE := ZAP.PRICE*1.2;
ELSE
NEW_PRICE := ZAP.PRICE*1.1;
END IF;
UPDATE BOOKS
SET PRICE = NEW_PRICE --обновление цены
161
WHERE CURRENT OF KUR;
END LOOP;
CLOSE KUR; --явное закрытие курсора
COMMIT; --завершение транзакции
END;
При запуске программы с помощью SQL*PLUS, необходимо указы-
вать в строке, следующей за последним оператором, косую черту (/),
чтобы программа выполнилась.
б) Использование курсора с параметром:
DECLARE
CURSOR KUR (GANR BOOKS.GENRE%TYPE) IS --курсор
имеет параметр
SELECT CODE_BOOK, PRICE FROM BOOKS
WHERE GENRE=GANR FOR UPDATE OF PRICE;
ZAP KUR%ROWTYPE;
NEW_PRICE BOOKS.PRICE%TYPE;
BEGIN
OPEN KUR ('Фантастика'); -- значение параметра
LOOP
FETCH KUR INTO ZAP;
EXIT WHEN KUR%NOTFOUND;
IF ZAP.PRICE < 2000 THEN
NEW_PRICE := ZAP.PRICE*1.2;
ELSE
NEW_PRICE := ZAP.PRICE*1.1;
END IF;
UPDATE BOOKS SET PRICE = NEW_PRICE
WHERE CURRENT OF KUR;
END LOOP;
CLOSE KUR;
COMMIT;
END;
в) Использование цикла FOR с курсором:
DECLARE
NEW_PRICE BOOKS.PRICE%TYPE;
CURSOR KUR IS
SELECT CODE_BOOK, PRICE FROM BOOKS
WHERE GENRE = 'Фантастика' FOR UPDATE OF PRICE;
BEGIN
162
FOR ZAP IN KUR LOOP --неявная обработка курсора
IF ZAP.PRICE < 2000 THEN --переменная ZAP неявно объяв-
ляется системой
NEW_PRICE := ZAP.PRICE*1.2;
ELSE
NEW_PRICE := ZAP.PRICE*1.1;
END IF;
UPDATE BOOKS SET PRICE = NEW_PRICE
WHERE CURRENT OF KUR;
END LOOP;
COMMIT;
END;
Достарыңызбен бөлісу: |