- •ВВЕДЕНИЕ
- •1. ВВЕДЕНИЕ В PL/SQL
- •1.1. ОПИСАНИЕ PL/SQL
- •1.2. ПРЕИМУЩЕСТВА PL/SQL
- •2. КОМАНДЫ DATA DEFINITION LANGUAGE (DDL)
- •2.1. ОСНОВНЫЕ ОБЪЕКТЫ ORACLE
- •2.2. ТАБЛИЦЫ
- •2.5. ИЗМЕНЕНИЯ ОБЬЕКТОВ
- •2.3. ПРЕДСТАВЛЕНИЕ (VIEW)
- •2.4. ИНДЕКС
- •КОНТРОЛЬНЫЕ ВОПРОСЫ К ГЛАВЕ 2
- •3. ЯЗЫК ORACLE SQL
- •3.3. ВЫБОРКА
- •3.4. ОБРАБОТКА ОШИБОК
- •3.5. ВЫРАЖЕНИЯ
- •КОНТРОЛЬНЫЕ ВОПРОСЫ К ГЛАВЕ 3
- •4. ЯЗЫК PL/SQL
- •4.1. ТИПЫ ДАННЫХ PL/SQL
- •4.2. СТРУКТУРА ПРОГРАММЫ НА PL/SQL
- •4.3. УПРАВЛЕНИЕ ВЫПОЛНЕНИЕМ ПРОГРАММЫ
- •4.4. УЧЕБНАЯ БАЗА ДАННЫХ
- •4.5. КУРСОРЫ
- •4.6. ОБРАБОТКА ИСКЛЮЧИТЕЛЬНЫХ СИТУАЦИЙ
- •4.7. СОЗДАНИЕ ПОЛЬЗОВАТЕЛЬСКИХ ПРОЦЕДУР И ФУНКЦИЙ
- •4.8. ПАКЕТЫ PL/SQL
- •4.9. ТРИГГЕРЫ БАЗЫ ДАННЫХ
- •ЗАКЛЮЧЕНИЕ
- •СПИСОК ЛИТЕРАТУРЫ
При этом:
−объявлять record_name, открывать и закрывать курсор – не следует;
−при использовании (select_expr) объявлять курсор – так же не следует;
−частое использовании (select_expr) снижает читабельность реальной программы.
В следующем примере курсорный цикл FOR неявно объявляет запись emp_rec как принадлежащую типу c1%ROWTYPE:
DECLARE
CURSOR c1 IS SELECT ename, sal, hiredate, deptno FROM
emp; BEGIN
FOR emp_rec IN c1 LOOP salary_total := salary_total + emp_rec.sal; END LOOP; END;
УПРАЖНЕНИЯ
1.С учётом сказанного, создать новый вариант программы выборки строк таблицы LECTURE с использованием курсоров, лишённый указанных выше недостатков. (Применить циклы LOOP и WHILE LOOP.)
2.Применить цикл FOR LOOP с явным объявлением кусора.
3.Применить цикл FOR LOOP с подзапросом (SELECT).
4.6. ОБРАБОТКА ИСКЛЮЧИТЕЛЬНЫХ СИТУАЦИЙ
Большинство развитых языков программирования обладает встроенными механизмами обработки исключительных ситуаций. Соответствующие языковые средства предусмотрены и в PL/SQL. При возникновении в системе предопределённой или описанной пользователем ситуации происходит автоматическая передача управления в нужный фрагмент блока EXCEPTION программы на PL/SQL, где и происходит предусмотренная обработка возникшей исключительной ситуации.
Некоторые предопределённые исключительные ситуации PL/SQL представлены в табл. 4.7. Полный перечень исключительных ситуаций может быть найден в руководстве по языку PL/SQL.
Рассмотрим пример программы с обработкой исключительных ситуаций. В тексте программы пропущен оператор открытия курсора, поэтому при обращении к методу %FOUND неоткрытого курсора возникнет исключительная си-
туация INVALID_CURSOR.
58
4.7. Некоторые исключительные ситуации
Имя исключительной ситуации |
Описание предопределённой исключительной ситуации |
|
|
LOGIN_DENIED |
Неуспешное подключение к серверу (например, |
|
введён неверный пароль) |
|
|
NOT_LOGGED_ON |
Попытка выполнить действие без подключения к |
|
серверу ORACLE |
|
|
INVALID_CURSOR |
Ссылка на недопустимый курсор или недопус- |
|
тимая операция с курсором |
|
|
NO_DATA_FOUND |
Не найдены данные, соответствующие операто- |
|
ру SELECT INTO |
|
|
DUP_VAL_ON_INDEX |
Попытка вставить значение-дубликат в столбец с |
|
ограничением на уникальность значения |
|
|
TOO_MANY_ROWS |
Оператор SELECT INTO возвращает более од- |
|
ной строки в переменную |
|
|
VALUE_ERROR |
Арифметическая ошибка, ошибка преобразова- |
|
ния или усечения |
|
|
TIMEOUT_ON_RESOURCE |
Блокировка по времени при ожидании ресурса |
|
|
ZERO_DIVIDE |
Деление на ноль |
|
|
INVALID_NUMBER |
Неудачная попытка преобразования к типу |
|
NUMBER |
|
|
STORAGE_ERROR |
Внутренняя ошибка языка, устанавливается, ес- |
|
ли PL/SQL недостаточно памяти |
|
|
PROGRAM_ERROR |
Внутренняя ошибка PL/SQL |
|
|
CURSOR_ALREADY_OPEN |
Попытка открыть курсор, который уже открыт |
|
|
Пример 4.18.
SQL>DECLARE
Argl LECTURE.LECTURE_ID%TYPE; Arg2 LECTURE.SURNAME%TYPE;
АгдЗ LECTURE.NAME%TYPE;
Arg4 LECTURE.FAC_ID%TYPE;
Cursor Curl IS SELECT * FROM LECTURE; BEGIN
FETCH Curl INTO Argl,Arg2,АгдЗ,Arg4; WHILE Curl%FOUND
59
LOOP
FETCH Curl INTO Argl,Arg2,АгдЗ,Arg4; END LOOP;
EXCEPTION
WHEN INVALID_CURSOR THEN
DBMS_OUTPUT.PUT_LINE(‘Ошибка приложения.He открыт
курсор’); END;
/
Для обработки исключительных ситуаций, не входящих в перечень стандартных, можно использовать специальный обработчик PL/SQL OTHERS или описать пользовательскую исключительную ситуацию и запрограммировать ее обработку. Ключевое слово OTHERS блока EXCEPTION определяет механизм универсальной обработки исключительных ситуаций, не вошедших в список ситуаций, обрабатываемых явно в блоке EXCEPTION. Введем в текст программы запрещенную операцию деления на ноль и обработаем данную исключительную ситуацию в списке OTHERS. (На самом деле в ORACLE предопределена исключительная ситуация ZERO_DIVIDE, но в данном примере это не важно, а важно то, что ее нет в списке блока EXCEPTION.)
Пример 4.19.
SQL> DECLARE
Argl LECTURE.LECTURE_ID%TYPE; Arg2 LECTURE SURNAME%TYPE;
Arg3 LECTURE.NAME%TYPE;
Arg4 LECTURE.FAC_ID%TYPE;
Cursor Curl IS SELECT * FROM LECTURE; Arg5 NUMBER:=1;
BEGIN
Arg5:=Arg5/0.0;
WHILE Curl%FOUND LOOP
FETCH Curl INTO Argl,Arg2,Arg3,Arg4,Arg5; END LOOP;
EXCEPTION
WHEN INVALID_CURSOR THEN
DBMS_OUTPUT.PUT_LINE(‘Ошибка приложения. He открыт
курсор’);
WHEN OTHERS THEN
DBMS OUTPUT.PUT_LINE (‘Heдиагностированная ошибка прило-
жения’); END;
/
Исключительная ситуация, определяемая пользователем, должна быть описана в блоке DECLARE программы. Используется следующий синтаксис описания исключительной ситуации:
имя исключительной_ситуации EXCEPTION.
60
В программе условие возникновения исключительной ситуации определяется стандартными средствами, обычно операторами IF..THEN. После обнаружения условий возникновения исключительной ситуации она генерируется оператором RAISE, который имеет следующий синтаксис:
RAISE имя_исключительной ситуации.
Оператор RAISE генерирует исключительную ситуацию и передаёт управление на соответствующий обработчик исключительной ситуации, который определен в блоке EXCEPTION. В качестве примера в роли исключительной ситуации рассмотрим превышение значения Argl порога, равного 20.
Пример 4.20.
SQL>DECLARE
Argl LECTURE.LECTURE_ID%TYPE; Arg2 LECTURE.SURNAME%TYPE;
Arg3 LECTURE.NAME%TYPE;
Arg4 LECTURE.FAC_ID%TYPE;
Special_case EXCEPTION; – Пользовательская исключительная ситуация
Cursor Curl IS SELECT * FROM LECTURE; BEGIN
OPEN Curl;
FETCH Curl INTO Argl,Arg2,Arg3,Arg4; WHILE Curl%FOUND
LOOP
FETCH Curl INTO Argl,Arg2,Arg3,Arg4;
IF Argl>20 THEN RAISE Special_case; END IF; END LOOP;
EXCEPTION
WHEN Special_case THEN
DBMSJDUTPUT.PUT_LINE('Пользовательская Исключительная
ситуация');
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE(‘Heдиагностированная ошибка'); END;
/
УПРАЖНЕНИЯ
1.Сделать выборку из таблицы STUDENT с использованием курсора и цикла с методом %FOUND или %NOTFOUND для получения данных о студентах, живущих в Москве.
2.Сделать выборку из таблицы SUBJECT с использованием курсора и цикла с методом %FOUND или %NOTFOUND для получения данных о предметах во 2-м семестре.
61
