- •5. Назначение языка pl/sql и его языковых конструкций
- •5.1. Начальные сведения
- •5.2. Языковые конструкции, обеспечивающие модульность
- •Хранимые процедуры
- •Хранимые функции
- •Триггеры
- •Отличие хранимых процедур от sql-сценариев
- •5.3. Структура блока pl/sql
- •Секция заголовка
- •Секция объявлений
- •Выполняемая секция
- •Секция исключений
- •5.4. Создание простой pl/sql-процедуры
- •Вызов процедур и функций
- •5.5. Переменные и константы pl/sql
- •Объявление переменных pl/sql
- •Объявление констант pl/sql
- •Присваивание значений переменным
- •Использование переменных
Секция исключений
В ходе выполнения PL/SQL-оператора может возникнуть ошибка, которая сделает невозможным дальнейшее выполнение программы. Такие исключительные ситуации называются исключениями (exceptions). Пользователя, вызвавшего процедуру, нужно проинформировать о возникновении исключения, а также о причинах, его вызвавших. Для этого можно выдать пользователю содержательное сообщение об ошибке или предпринять некоторые корректирующие действия и повторить операцию, выполнявшуюся до возникновения ошибки.Можно также откатить изменения, которые были произведены в базе данных к этому моменту.
PL/SQL помогает во всех этих случаях, предоставляя средства обработки исключений (exception handling). Секция исключений имеет следующую структуру:
EXCEPTION
WHEN имя_исключения
THEN
действия, предпринимаемые при возникновении исключения
WHEN имя_исключения
THEN
действия, предпринимаемые при возникновении исключения
Секция исключений начинается с ключевого слова EXCEPTION и продолжается до конца блока. Каждому исключению соответствует оператор WHEN имя_исключения, указывающий, что должно быть сделано при возникновении данного исключения. В приведенном выше примере таких операторов три, все они выводят текст на экран SQL*Plus. Пакет DBMS_OUTPUT и процедура PUT_LINE являются частью базы данных Oracle; вместе они позволяют построчно отображать текст на экране SQL*Plus.
Все операторы, находящиеся между оператором, вызвавшим ошибку, и секцией исключений, игнорируются. Таким образом, в блоке рассматриваемого примера присваивание значения 7 переменной Num_b не выполняется.
Выполнение оператора, указанного в секции исключений, называется обработкой исключения (exception handling).
Процесс, включающий в себя обнаружение ошибки, определение, какое исключение описывает ее наилучшим образом, и передачу PL/SQL информации, позволяющей найти соответствующий код в секции исключений, называется возбуждением исключения (raising exception). В коде примера исключение возбуждает сам PL/SQL, обнаружив попытку деления на нуль. В PL/SQL это исключение имеет предопределенное имя — ZERO_DIVIDE. Во многих ситуациях ошибку должен обнаруживать код, написанный программистом, а не PL/SQL.
5.4. Создание простой pl/sql-процедуры
Рассмотренных языковых конструкций достаточно для написания законченной PL/SQL-процедуры, код которой приводится ниже:
CREATE PROCEDURE my_first_proc IS
greetings VARCHAR2 (20) ;
BEGIN
greetings := 'Hello World';
dbms_output .put_line (greetings) ;
END my_first_proc;
/
Синтаксис создания хранимой процедуры имеет вид:
CREATE PROCEDURE спецификация_процедуры IS тело_процедуры
В приведенном примере спецификацией процедуры является ее имя, а телом — все, что идет дальше, вплоть до завершающей точки с запятой. При создании функции ключевое слово PROCEDURE заменяется на FUNCTION:
CREATE FUNCTION спецификация_функции IS тело_функции
Прямой слэш (/) сообщает PL/SQL, что ввод программы завершен и нужно перейти к выполнению команд. Процедуру или функцию можно создать заново, использовав команду CREATE OR REPLACE вместо CREATE. Это приведет к уничтожению старого определения и замене его на новое. При отсутствии старого определения будет просто создано новое.
CREATE OR REPLACE спецификация_процедуры IS тело_процедуры
Можно вызывать эту процедуру из SQL*Plus следующими командами:
set serveroutput on
EXECUTE my_first_proc;
Команда SET SERVEROUTPUT ON позволяет увидеть выходные данные. Команда EXECUTE запускает процедуру на выполнение. Также можно вызвать процедуру из анонимного блока, как показано ниже:
BEGIN
my_first_proc;
END;
/