Рассмотрим следующие таблицы.
CREATE TABLE subscriptions
(
id SERIAL PRIMARY KEY,
state text NOT NULL CHECK (state IN ('trial', 'expired', 'active', 'cancelled')),
created_at timestamptz NOT NULL
);
CREATE TABLE subscriptions_history (LIKE subscriptions);
ALTER table subscriptions_history ADD COLUMN change_type CHARACTER VARYING(6);
ALTER table subscriptions_history ADD COLUMN change_time timestamp without time zone;
ALTER TABLE subscriptions_history ADD CONSTRAINT subscriptions_history_change_type_check CHECK ((((change_type)::text = 'INSERT'::text) OR ((change_type)::text = 'UPDATE'::text) OR ((change_type)::text = 'DELETE'::text)));
Я написал следующую функцию триггера, которая вставляет строку в subscriptions_history
при каждом изменении (вставке, обновлении, удалении) в subscriptions
таблице.
CREATE OR REPLACE FUNCTION add_to_subscriptions_history()
RETURNS TRIGGER
SET SCHEMA 'public'
LANGUAGE plpgsql
AS $$
DECLARE
current_row RECORD;
BEGIN
IF (TG_OP = 'INSERT' OR TG_OP = 'UPDATE') THEN
current_row := NEW;
ELSIF (TG_OP = 'DELETE') THEN
current_row := OLD;
END IF;
INSERT INTO subscriptions_history (id, state, created_at, change_type, change_time) VALUES (current_row.id, current_row.state, current_row.created_at, TG_OP, now());
RETURN current_row;
END;
$$;
Триггер:
DROP TRIGGER IF EXISTS subscriptions_trigger ON subscriptions;
CREATE TRIGGER subscriptions_trigger
BEFORE INSERT OR DELETE OR UPDATE ON subscriptions
FOR EACH ROW EXECUTE PROCEDURE add_to_subscriptions_history();
Эта реализация работает нормально, но у меня есть множество таблиц, которым нужна такая история, и я не хочу писать функцию триггера для каждого и каждого один из них. Я хотел бы обобщить функцию add_to_subscriptions_history()
, чтобы она могла обрабатывать любую таблицу.
Моя единственная идея - каким-то образом передать таблицу и ее таблицу истории в функцию триггера в качестве параметра и перебирать записи столбцы во время вставки. Как я могу это сделать? Есть альтернативные идеи, скрипты?