Информационное обеспечение



бет14/56
Дата05.03.2023
өлшемі256,49 Kb.
#71567
түріПрактикум
1   ...   10   11   12   13   14   15   16   17   ...   56
Использование курсорных циклов FOR. Обработка курсоров с помощью циклов FOR в некоторых случаях значительно упрощает код программы. Цикл FOR с курсором – это цикл, связанный с курсором, явно заданным или пред- ставленным в виде оператора SELECT непосредственно в цикле.
Перепишем предыдущий пример с использованием курсоров FOR:

-- Изменение заработной платы сотруднику с курсорным циклом FOR DECLARE


-- отдел IT
vdep departments.department_id%TYPE := 60;
-- % повышения (снижения) заработной платы
pctsal NUMBER (5, 2) := 30;
newsal employees.salary%TYPE; BEGIN
FOR listemp IN (SELECT emp.employee_id, emp.job_id, emp.salary, jobs.min_salary, jobs.max_salary FROM employees emp, jobs WHERE department_id = vdep AND emp.job_id = jobs.job_id)
LOOP newsal := listemp.salary * (100 + pctsal) / 100;
IF newsal < listemp.min_salary THEN newsal := listemp.min_salary; ELSIF newsal > listemp.max_salary THEN newsal := listemp.max_salary; END IF;
DBMS_OUTPUT.put_line ( 'Cотрудник '
|| listemp.employee_id
|| ' старая заработная плата ='
|| listemp.salary
|| ' новая заработная плата ='
|| ' = '|| newsal);
END LOOP;
END;
/


В курсорном цикле FOR автоматически объявляется переменная или запись, с помощью которой можно считывать записи, курсор не нужно явно открывать и закрывать. Закрывается курсор сам, когда из него выбирается последняя строка.
Обработка исключительных ситуаций. В программах PL/SQL подпро- граммы обработки ошибок представляют собой обработчики исключительных ситуаций EXCEPTION. Как только инициируется исключение, нормальная ра- бота программы прерывается и управление передается в блок обработки ис- ключений. Поэтому важно помнить, что когда при проектировании программ необходимо перехватить и обработать исключение, не заканчивая на этом рабо- ту основной программы, необходимо пользоваться вложенными блоками.
Для того чтобы перехватить исключение, необходимо написать для него обработчик. В одном разделе EXCEPTION может быть написано несколько об- работчиков. По структуре они напоминают оператор CASE и имеют следую- щий синтаксис:

EXCEPTION


WHEN исключение_1 THEN
обработка_ исключения_1_исполняемые_операторы WHEN исключение_2 THEN
обработка_ исключения_2_исполняемые_операторы
. . .
WHEN исключение_n THEN
обработка_ исключения_n_исполняемые_операторы
[ WHEN OTHERS THEN
обработка_прочих_исключений_исполняемые_операторы ] END;

Также возможен вариант объединения нескольких исключений в одном обработчике. Например:


WHEN NO_DATA_FOUND OR ZERO_DIVIDE THEN


Если для инициированного исключения не найдено ни одного обработчи- ка, но при этом присутствует обработчик WHEN OTHERS, то его обработка выполняется именно в этом блоке. Если исключение все же не было обработа- но, то PL/SQL возвращает исключение в вызвавшую родительскую программу или же в ту среду, из которой была запущена программа. Это может быть SQL*Plus, TOAD или любое другое клиентское приложение.


Исключения бывают двух видов:

  • определенные программистом (user-defined exception);

  • системные, например, нехватка памяти или нарушение целостности БД. Исключения, определяемые программистом, объявляются в блоке декла-

рации, там же, где объявляются переменные и курсоры. Например:

DECLARE
vjob_id jobs.job_id%TYPE :='0'; exp_badempid EXCEPTION; BEGIN


NULL; END;
/
Область действия объявленных исключений аналогична области действия переменных и курсоров.
Системные исключения генерируются системой и, как правило, выдаются в формате

ORA-номер_ошибки сообщение_об_ошибке


Некоторые из системных исключений имеют имена – это так называемые предопределенные исключения. Список таких исключений приведен в прил. 4 (табл. П.4.1). Например, программа распознает исключительную ситуацию NO_DATA_FOUND в случае, если в результирующем множестве оператора SELECT INTO нет строк; исключительную ситуацию TOO_MANY_ROWS – если в результирующем множестве этого оператора более одной строки; ис- ключительную ситуацию DUP_VAL_ON_INDEX (повторяющееся значение в индексе) – если оператор INSERT или UPDATE дублирует ключевое значение, уже находящееся в таблице.


При обработке исключений запоминать номера ошибок бывает затрудни- тельно. Поэтому в PL/SQL имеется механизм связывания номера ошибки с его названием с помощью директивы компилятору – предопределенной прагмы EXCEPTION_INIT, сообщающей компилятору имя исключения, которое ассоци- ируется с конкретным кодом ошибки Oracle. Это позволяет обращаться к любо- му внутреннему исключению по имени, написав для него специальный обработ- чик. Прагма EXCEPTION_INIT указывается в декларативной части блока, под- программы или пакета PL/SQL c использованием следующего синтаксиса:

PRAGMA EXCEPTION_INIT (имя_исключения, код_ошибки_Oracle);


где имя_исключения – это имя исключения, ранее уже объявленного в этом блоке.


Пусть программа в качестве аргумента принимает цифровое значение в виде символьной строки и переводит его в числовой формат. Выполним этот блок в SQL*Plus.

DECLARE
vals VARCHAR2 (10) := :S;


valn NUMBER;
BEGIN
DBMS_OUTPUT.PUT_LINE ('строка ='||vals); valn := TO_NUMBER (vals); DBMS_OUTPUT.PUT_LINE ('число ='||valn); END;
/

При выполнении получим приглашение для ввода параметра S и введем, например, число 123.36, в результате получим:


строка = 123.36


число = 123.36 Statement processed.

Когда пользователь задает аргумент в правильном формате (т. е. пригод- ном для конвертирования в число), программа отрабатывает нормально. Но стоит ввести неверно заданный аргумент, например, 123/36, то получим


ORA-06502: PL/SQL: numeric or value error: character to number conversion error Хорошим стилем программирования является обработка подобных ситу-
аций на этапе написания программного кода, в данном случае воспользуемся
прагмой EXCEPTION_INIT.
DECLARE
vals VARCHAR2 (10) := :S;
valn NUMBER; expChar_To_number EXCEPTION;
PRAGMA EXCEPTION_INIT (expChar_To_number, -06502); BEGIN
DBMS_OUTPUT.put_line ('строка =' || vals); valn := TO_NUMBER (vals); DBMS_OUTPUT.PUT_LINE ('число =' || valn); EXCEPTION
WHEN expChar_To_number THEN
DBMS_OUTPUT.PUT_LINE ('ошибка: аргумент ' || vals || ' не является числом');
END;
/

Инициирование исключений. Ссылаться на исключения можно несколь- кими способами.



    1. При помощи оператора RAISE:

RAISE [имя_пакета].имя_исключения; или просто:


RAISE;

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


Второй вариант используется тогда, когда в блоке EXCEPTION необхо- димо повторно инициировать исключение.
1. Oracle предоставляет возможность инициировать исключения при по- мощи процедуры RAISE_APPLICATION_ERROR, которая в отличие от опера- тора RAISE позволяет связать с номером исключений сообщение об ошибке и не требует заранее определенного исключения:

RAISE_APPLICATION_ERROR (номер_ошибки, сообщение_об_ошибке);


где номер_ошибки – это целое число в пользовательском диапазоне от –20 999 до – 20 000; сообщение_об_ошибке – строка, длина которой не превышает 2048 символов.


При обработке исключений в ветке WHEN OTHERS обработчику иногда необходимо идентифицировать возникающую ошибку. Для этого имеются встро- енные функции SQLCODE и SQLERRM. Функция SQLCODE возвращает номер
текущей ошибки (0 указывает, что в стеке нет ни одной ошибки). Функция SQLERRM возвращает текстовое сообщение о текущей или указанной разработ- чиком ошибке. Для исключений, определяемых пользователем, SQLCODE воз- вращает 1, a SQLERRM возвращает «User-defined Exception» (определенное поль- зователем исключение). Максимальная длина строки, возвращаемой SQLERRM, составляет 512 байт. Значения функций SQLCODE и SQLERRM сначала присваи- ваются локальным переменным, и только потом эти переменные указываются в SQL-операторе. Например, эти функции часто используются для сохранения в до- полнительной таблице сведений об ошибках (протоколирование):
CREATE TABLE errors (num number, msg varchar2(256));

DECLARE
b number;


err_num NUMBER; err_msg CHAR (100); BEGIN
b := 2/0; EXCEPTION
WHEN OTHERS THEN err_num := SQLCODE; err_msg := SUBSTR(SQLERRM, 1, 100);
INSERT INTO errors VALUES (err_num, err_msg); END;
/

В примере переменная err_msg ограничена 100 символами. Если текст со- общения об ошибке превышает 100 символов, операция err_msg := SQLERRM; сама вызывает стандартную исключительную ситуацию VALUE_ERROR. Во избежание этого используется встроенная функция SUBSTR, обеспечивающая присваивание переменной v_ErrorText не более чем 100 символов.


При обработке ошибок можно не только выдавать приемлемые для поль- зователя сообщения об ошибках, вести протоколирование, но и просто их игно- рировать.

DECLARE
vals VARCHAR2 (10) := :S; valn NUMBER :=0;


BEGIN BEGIN
-- смогли конвертировать без ошибок valn := TO_NUMBER (vals); EXCEPTION
WHEN OTHERS THEN
-- игнорируем ошибку конвертации
NULL; END;
DBMS_OUTPUT.PUT_LINE ('строка =' || vals); DBMS_OUTPUT.PUT_LINE ('число =' || valn); END;
/

Получим результат:


строка =123/36 число =0




Хранимые процедуры и функции. Хранимые процедуры и функции в от- личие от анонимных блоков сохраняются в базе данных и наряду с таблицами, представлениями и другими структурными единицами являются самостоятель- ными объектами БД Oracle. Процедуры и функции сохраняются в откомпили- рованном виде и по мере их вызова загружаются в разделяемый пул, поддержи- ваемый СУБД, откуда удаляются по мере заполнения пула в порядке частоты использования кода процедуры или функции. Наиболее редко используемый код удаляется раньше и при очередном вызове снова загружается в пул с диска. Такая организация способствует производительности выполнения вызываемых процедур и функций, поскольку исключает постоянную загрузку с диска ис- полняемого кода.


Достарыңызбен бөлісу:
1   ...   10   11   12   13   14   15   16   17   ...   56




©emirsaba.org 2024
әкімшілігінің қараңыз

    Басты бет