Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
СУБД Oracle / Лекции / Лек_ORAC / L67 / Обработка ошибок.doc
Скачиваний:
46
Добавлен:
16.04.2013
Размер:
71.17 Кб
Скачать

Обработка ошибок

При возникновении исключительных ситуаций важно выдавать дружест­венные к пользователю сообщения об ошибках. Об исключениях уже упоминалось в разделе, посвященном базовым блокам PL/SQL. Теперь настало время рассмотреть их подробнее.

Исключения

Исключение – это состояние ошибки, которое активизируется – или возбуждается – при возникновении некоторой проблемы. Существует много разных исключений, каждое из которых связано с определенным типом проблем. При возникновении исключительной ситуации выполнение кода останавливается на операторе, который возбудил исключение, и управление передается той части блока, которая обрабатывает это исключение. Если блок не содержит выполняемой секции, PL/SQL пытается найти выполняемую секцию во включающем базовом блоке (enclosing basic block), т.е. в блоке, который является внешним по отношению к коду, возбудившему исключение. Если в непосредственном включающем блоке отсутствует обработчик данного исключения, то поиск продолжается в блоках следующих уровней, пока не будет найден подходящий обработчик, а если его найти не удается, то выполнение программы прекращается с выдачей сообщения о необрабатываемой ошибке.

Часть блока, предназначенная для обработки исключений, – это идеальное место для выдачи информативных сообщений об ошибках и выполнения очистки (cleanup), позволяющей избавиться от всего, что могло бы в дальнейшем вызвать путаницу или проблемы. Если исключение было возбуждено в ходе выполнения процедуры вставляющей строки в таблицу, то типичная процедура очистки может включать в себя оператор ROLLBACK.

После того как управление было передано обработчику исключения, оно уже не возвращается оператору, ставшему причиной этого исключения. Вместо этого управление передается оператору включающего базового блока, который следует сразу за вызовом вложенного блока или процедуры/функции.

Системные исключения

Вы уже знакомы с исключением ZERO_DIVIDE, предопределенным в PL/SQL. Существует довольно много других системных исключений, которые распознаются и возбуждаются PL/SQL или Oracle. В таблице 1 приведен более полный список системных исключений.

В PL/SQL можно выдавать пользователям информацию об ошибке двумя способами. Первый способ – использовать команду SQLCODE, которая возвращает код ошибки. Этот код представляет собой отрицательное число, обычно равное номеру ошибки ORA, которая выводится при завершении приложения, если исключение осталось необработанным. Второй способ – возвращать текстовое сообщение, описывающее ошибку. Неудивительно, что соответствующая команда называется SQLERRM. В обработчике исключения можно использовать как SQLCODE, так и SQLERRM. Замечание: не у всех системных исключений есть имена.

Таблица 1. Системные исключения

Системное исключение, код ошибки

Причина возбуждения

CURSOR_ALREADY_OPEN

ORA-06511

Попытка открыть уже открытый курсор

DUP_VAL_ON_INDEX

ORA-00001

Попытка вставить повторяющееся значение в столбец, имеющий уникальный индекс, а следовательно, ограничение уникальности

INVALID_CURSOR

ORA-01001

Попытка применить команду FETCH к неоткрытому курсору или попытка закрыть курсор, который не открывался

NO_DATA_FOUND

ORA-01403

Попытка выполнить SELECT INTO, когда SELECT возвращает нулевое количество строк (а также другие причины, описание которых выходит за рамки этой книги)

PROGRAM_ERROR

ORA-06501

Внутренняя ошибка. Обычно означает, что вам нужно обратиться в службу поддержки Oracle

STORAGE_ERROR

ORA-06500

Программе не хватает системной памяти

TIMEOUT_ON_RESOURCE

ORA-00051

Программа слишком долго ожидала доступности некоторого ресурса

TOO_MANY_ROWS

ORA-01422

SELECT INTO в PL/SQL вернул более одной строки

VALUE_ERROR

ORA-06502

PL/SOL встретил неправильное преобразование или усечение данных, или неправильное ограничение на данные

ZERO_DIVIDE

ORA-01476

Попытка деления на нуль

OTHERS

Все прочие исключения и внутренние ошибки, которые не охватываются исключениями, опреде­ленными в базовом блоке. Используется в тех слу­чаях, когда вы точно не знаете, какое именованное исключение предстоит обрабатывать, и хотите обрабатывать любые возбуждаемые исключения

Теперь вернемся к самому первому примеру этой главы и используем в нем SQLCODE и SQLERRM. Ниже приведен исходный код примера и результаты его запуска (рис.1).

DECLARE

Num_a NUMBER := 6;

Num_b NUMBER;

BEGIN

Num_b := 0;

Num_a := Num_a / Num_b;

Num_b := 7;

dbms_output.put_line(' Value of Num_b '|| Num_b);

EXCEPTION

WHEN ZERO_DIVIDE THEN

DECLARE

err_num NUMBER := SQLCODE;

err_msg VARCHAR2(512) := SQLERRM;

BEGIN

dbms_output.put_line('ORA Error Number ' || err_num);

dbms_output.put_line('ORA Error message ' || err_msg);

dbms_output.put_line('Value of Num_a ' || Num_a);

dbms_output.put_line('Value of Num_b ' || Num_b);

END;

END;

/

SQL> set serveroutput on

SQL> DECLARE

2 num_a NUMBER := 6;

3 num_b NUMBER;

4 BEGIN

5 num_b := 0;

6 num_a := num_a / num_b;

7 num_b := 7;

8 dbms_output.put_line(' Value of num_b '|| num_b);

9 EXCEPTION

10 WHEN ZERO_DIVIDE

11 THEN

12 DECLARE

13 err_num NUMBER := SQLCODE;

14 err_msg VARCHAR2(512) := SQLERRM;

15 BEGIN

16 dbms_output.put_line('ORA Error Number '|| err_num);

17 dbms_output.put_line('ORA Error message ' || err_msg);

18 dbms_output.put_line('Value of num_a ' || num_a);

19 dbms_output.put_line('Value of num_b ' || num_b);

20 END;

21 END;

22 /

ORA Error Number -1476

ORA Error Message ORA-01476: divisor is equal to zero

Value of num_а 6

Value of num_b 0

PL/SQL procedure successfully completed.

SQL>

Рис. 1. Использование SQLCODE и SQLERRM при обработке системных исключений