Иллюстрированный самоучитель по PostgreSQL

PL/pgSQL и триггеры

В листинге 11.52 приведен пример определения трнггерной функции PL/pgSDL, использующей некоторые из перечисленных переменных. Триггерная функция check_shipment_addition() вызывается после выполнения операции INSERT или UPDATE с таблицей shipments.

Функция check_shipment_addition() убеждается в том, что каждая новая запись содержит действительный код покупателя и код ISBN книги. Затем общее количество экземпляров в таблице stock уменьшается на 1, если триггер сработал по команде SQL INSERT (но не по команде UPDATE!)

Листинг 11.52. Триггерная функция check_shipment_addition().

CREATE FUNCTION check_shipment_addition () RETURNS opaque AS '
DECLARE
--Объявление переменной для хранения кода покупателя,
idjiumber integer;
--Объявление переменной для хранения кода ISBN.
book_isbn text;
BEGIN
--Если в таблице customers существует код. совпадающий с кодом
--покупателя в таблице new. присвоить его переменной idjiumber.
SELECT INTO idjiumber id FROM customers WHERE id = NEW.customer_id:
--Если совпадение не найдено, инициировать исключение.
IF NOT FOUND THEN
RAISE EXCEPTION "Invalid customer ID number.":
END IF;
--Если в таблице editions существует код ISBN, совпадающий с кодом
--ISBN в таблице new. присвоить его переменной bookjsbn.
SELECT INTO bookjsbn isbn FROM editions WHERE isbn = NEW.isbn;
--Если совпадение не найдено, инициировать исключение.
IF NOT FOUND THEN
RAISE EXCEPTION "Invalid ISBN.";
END IF:
--Если обе предыдущие проверки завершились успешно.
--обновить количество экземпляров.
IF TG_OP – "INSERT" THEN
UPDATE stock SET stock = stock -1 WHERE isbn = NEW.isbn;
END IF:
RETURN NEW:
END;
' LANGUAGE 'plpgsql':

После создания функции check_shipment_addition() в таблице shipments устанавливается триггер для ее вызова. В листинге 11.53 приведен синтаксис команды, создающей триггер check_shipment в базе данных booktown (для клиента psql).

Листинг 11.53. Триггер check_shipment.

booktown=# CREATE TRIGGER check_shipment
booktown-* BEFORE INSERT OR UPDATE
booktown-# ON shipments FOR EACH ROW
booktown-* EXECUTE PROCEDURE check_shipment_addition();
CREATE

Обратите внимание: функция check_shipment_addition() должна определяться в базе данных booktown до определения триггера, по которому она вызывается. Триггерные функции всегда определяются раньше триггеров.

За дополнительной информацией о триггерах обращайтесь к главе 7.

Если Вы заметили ошибку, выделите, пожалуйста, необходимый текст и нажмите CTRL + Enter, чтобы сообщить об этом редактору.