Базы данных

Триггеры в PostgreSQL

Захотелось посвятить одну запись триггерам. Люблю я их за то, что делают некоторую работу без моего участия, это так ценно 🙂

Как создать триггер?

Сначала напишем триггерную функцию, которая и будет выполнять некоторые действия при модификации той или иной таблицы. Предположим у нас есть таблица products, хранящая некоторые сведения о продукции на складе:

CREATE TABLE products
(
  product_id character varying(15) NOT NULL,
  product_name character varying(400) NOT NULL,
  amount integer DEFAULT 0,
  CONSTRAINT products_pkey PRIMARY KEY (product_id)
)

Поле amount отвечает за то количество продукции, что хранится на складе. Все поступления или расход продукции фиксируются в другой таблице — products_acts:

CREATE TABLE products_acts (
id serial not null,
product_id character varying(15) not null,
date_time timestamp without time zone DEFAULT now(),
act_type integer not null,
CONSTRAINT products_acts_pkey PRIMARY KEY (id),
CONSTRAINT products_acts_products_fkey FOREIGN KEY (product_id)
      REFERENCES products (product_id) MATCH SIMPLE
      ON UPDATE CASCADE ON DELETE RESTRICT
)

Если поле act_type = 0, значит происходит добавление продукции, если 1 — удаление.

Теперь перейдем к самой триггерной функции. Она будет автоматически подсчитывать актуальное количество продукции на складе, которое будет отображаться в поле products.amount:

CREATE OR REPLACE FUNCTION update_products_amount()
  RETURNS trigger AS
$BODY$begin
--если удаление:
if (TG_OP = 'DELETE' or TG_OP = 'UPDATE') then
--если удаляется запись о поступлении продукции
	if (OLD.act_type = 0) then update products set amount = amount - OLD.product_count where product_id = OLD.product_id;
	--если удаляется запись о сбыте продукции
	else update products set amount = amount + OLD.product_count where product_id = OLD.product_id;
	return OLD;
	--добавление продукции на складе
if (TG_OP = 'INSERT' or TG_OP = 'UPDATE') then
	--если добавляется запись о поступлении продукции
	if (OLD.act_type = 0) then update products set amount = amount + NEW.product_count where product_id = NEW.product_id;
	--если добавляется запись о сбыте продукции
	else update products set amount = amount - NEW.product_count where product_id = NEW.product_id;
	return NEW;
--при редактировании сначала нужно вернуть предыдущие значения, а затем присвоить новые
end if;
end;$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;

Осталось создать триггер для таблицы products_acts:

CREATE TRIGGER update_amount
  AFTER INSERT OR UPDATE OR DELETE
  ON products_acts
  FOR EACH ROW
  EXECUTE PROCEDURE update_products_amount();

Триггеры в PostgreSQL: 1 комментарий

Оставьте своё мнение...

Этот сайт использует Akismet для борьбы со спамом. Узнайте как обрабатываются ваши данные комментариев.