Автоматизация стандартных процедур
Предположим, вы написали на процедурном языке функцию, которая проверяет данные, переданные при вызове команды INSERT или UPDATE для таблицы shipments, и затем обновляет таблицу stock, снимая поставленный товар со складского учета. Такую функцию можно написать на любом языке, поддерживаемом PostgreSQL (кроме "чистого" SQL, о чем говорилось выше).
Прежде всего функция убеждается в том, что переданный код покупателя (customer_id) и код ISBN (isbn) присутствуют в таблицах customers и echtions. Если хотя бы один из кодов отсутствует, функция возвращает признак ошибки. Если оба кода присутствуют в таблицах, команда SQL выполняется, и после успешного завершения количество товара на складе в таблице stock автоматически уменьшается в соответствии с объемом поставки.
Триггер, создаваемый в листинге 7.35, срабатывает непосредственно перед выполнением команды INSERT или UPDATE в таблице shipments. Триггер вызывает функцию check_shipment addition() для каждой изменяемой записи.
Листинг 7.35. Создание триггера 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 настроен на выполнение функции check_shipment_addition() для команд INSERT и UPDATE, поэтому он достаточно надежно обеспечивает логическую целостность данных в полях customerjd и isbn. Ключевое слово ROW гарантирует, что каждая добавляемая или модифицируемая запись будет обработана функцией проверки check_argument_addition().
Функция check_shipment_addition() вызывается без аргументов, поскольку для проверки записей в ней используются внутренние переменные PL/pgSQL. Реализация функции check_shipments_addition() на языке PL/pgSQL приведена в главе 11.
Получение информации о триггерах
В PostgreSQL триггеры хранятся в системной таблице pg_trigger, что позволяет получить информацию о существующих триггерах на программном уровне. Структуру таблицы pg_trigger иллюстрирует табл. 7.3.
Таблица 7.3. Таблица pgjrigger.
Поле | Тип |
---|---|
tgrelid | old |
tgname | name |
tgfoid | old |
tgtype | smallint |
tgenabled | boo'i ean |
tgisconstraint | boolean |
tgconstrname | name |
tgconstrrelid | oid |
tgdeferrable | boolean |
tginltdef erred | boolean |
tgnargs | small int |
tgattr | int2vector |
tgargs | bytea |
Большинство полей, перечисленных в табл. 7.3, в прямых запросах не используется. Среди атрибутов триггеров в системной таблице pg_trigger центральное место занимают атрибуты tgrelid и tgname.
В поле tgrel id хранится идентификатор отношения, с которым связан данный триггер. Значение относится к типу oid и соответствует содержимому поля relfiIenode системной таблицы pg_class. В поле tgname хранится имя триггера, указанное в команде CREATE TRIGGER при его создании.