Обработка ошибок и исключений
Команда RAISE предназначена для инициирования ошибок и исключений в функциях PL/pgSQL. Она передает заданную информацию механизму PostgreSQL elog (стандартное средство ведения протокола ошибок — данные обычно направляются в файл /var/log/messages или $PGDATA/serverlog с одновременным выводом в поток stderr).
В команде RAISE также указывается уровень ошибки и строка, передаваемая PostgreSQL. Кроме того, в команду можно включить переменные и выражения, значения которых будут содержаться в выходных данных. Соответствующие позиции строки помечаются знаками процента (%). Синтаксис команды RAISE: RAISE уровень ''сообщение'' [. идентификатор [...] ]:
В табл. 11.1 приведены три допустимые значения уровня ошибки с краткими описаниями.
Таблица 11.1. Допустимые значения уровня ошибки
Значение | Описание |
DEBUG |
Команда уровня DEBUG направляет заданный текст в виде сообщения DEBUG: в журнал PostgreSQL и клиентской программе, если клиент подключен к кластеру базы данных, работающему в отладочном режиме. Команды RAISE уровня DEBUG игнорируются базами данных, работающими в режиме реальной эксплуатации |
NOTICE |
Команда уровня NOTICE направляет заданный текст в виде сообщения NOTICE: в журнал PostgreSQL и клиентской программе. Сообщение передается в любом режиме работы PostgreSQL |
EXCEPTION |
Команда уровня EXCEPTION направляет заданный текст в виде сообщения ERROR: в журнал PostgreSQL и клиентской программе. Ошибка уровня EXCEPTION также вызывает откат текущей транзакции |
В листинге 11.48 первая команда RAISE выводит отладочное сообщение, а вторая и третья команды выводят сообщение для пользователя. Обратите внимание на знак % в третьей команде — он отмечает позицию, в которой выводится значение an_i nteger. Наконец, четвертая команда RAISE выводит сообщение об ошибке и инициирует исключение, приводящее к отмене транзакции.
Листинг 11.48. Команда RAISE
CREATE FUNCTION raise_test () RETURNS integer AS '
DECLARE
-- Объявление целочисленной переменной для тестового вывода.
an_integer integer = 1;
BEGIN
- Вывести отладочное сообщение уровня
DEBUG. RAISE DEBUG "The raise_test() function began.":
an_integer = an_integer * 1;
-- Вывести сообщение об изменении переменной an_integer,
-- а затем вывести другое сообщение с ее новым значением.
RAISE NOTICE "Variable anjnteger was cnanged.";
RAISE NOTICE "Variable anjnteger's value is now £." anjnteger;
-- Инициировать исключение.
RAISE EXCEPTION "Variable % cnanged.
Transaction aborted. ",anjnteger:
RETURN 1:
END;
' LANGUAGE 'plpgsql':
В листинге 11.49 приведены результаты, полученные при вызове функции raise_test() из базы данных booktown. Отладочное сообщение DEBUG отсутствует, поскольку база данных работает не в отладочном режиме.
Листинг 11.49. Результаты вызова raise_test()
booktown=# SELECT raise_test();
NOTICE: Variable anjnteger was changed.
NOTICE: Variable anjnteger's value is now 2.
ERROR: Variable 2 changed. Aborting transaction.
Вызов функций
При вызове функции PL/pgSQL из кода PL/pgSQL имя функции обычно включается в команду SQL SELECT или в команду присваивания. Примеры:
SELECT функция (аргументы):
переменндя := функция(аргументы):
Подобный способ вызова функций при выборке и присваивании стал стандартным, поскольку любая функция PostgreSQL должна возвращать значение некоторого типа. Ключевое слово PERFORM позволяет вызвать функцию и проигнорировать возвращаемое значение. Синтаксис вызова функции с ключевым словом PERFORM: PERFORM функция (аргументы'):
В листинге 11.50 приведены примеры вызова функции PL/pgSQL с ключевым словом PERFORM и вызова другой функции PL/pgSQL посредством присваивания (в команде SELECT INTO). Функция ship_item() является удобной «оболочкой» для вызова функции add_sh1pment(). Она получает исходные данные, убеждается в существовании покупателя и книги, а затем передает данные add_shipment().
Листинг 11.50. Использование ключевого слова PERFORM
CREATE FUNCTION shipjtem (text.text.text) RETURNS integer AS '
DECLARE
-- Объявление псевдонимов для аргументов функции.
l_name ALIAS FOR $1: f_name ALIAS FOR $2;
bookjsbn ALIAS FOR $3:
-- Объявление переменной для хранения кода книги.
-- Переменная используется для проверки переданного кода ISBN.
book_id Integer:
-- Объявление переменной для хранения кода покупателя.
-- Переменная используется для проверки переданных данных покупателя.
customeMd integer;
BEGIN
-- Получить код покупателя при помощи ранее определенной функции.
SELECT INTO customer_id get_customer_id(l_name.f_name);
-- Если покупатель не найден, функция get_customerjd
-- возвращает -1. В этом случае вернуть -1 и выйти из функции.
IF customerjd = -1 THEN
RETURN -1:
END IF:
-- Получить код книги с заданным кодом ISBN.
SELECT INTO book id book id FROM editions WHERE isbn = book isbn:
-- Если данные книги отсутствуют в базе, вернуть -1.
IF NOT FOUND THEN
RETURN -1;
END IF;
-- Если книга и покупатель существуют.
-- сохранить информацию о поставке в базе.
PERFORM add_shipment(customer_id.bookjsbn);
-- Вернуть 1 - признак успешного выполнения функции.
RETURN 1:
END;
' LANGUAGE 'plpgsql':