Есть ли хороший способ запустить триггер для каждой записи в таблице postgres?

22

У меня есть система, в которой я не могу управлять дизайном некоторых таблиц (реплицируется через Slony-I), и поэтому у меня есть ряд того, что мы называем «теневыми таблицами», где я извлекаю некоторую информацию из реплицируемых таблиц и сохраните его в обработанной форме, в которой я нуждаюсь, при этом удаляя записи, которые я хочу игнорировать.

Прямо сейчас, после настройки новой реплики, я запускаю обновление и возвращаю себе значение (например, UPDATE tablename SET field=field), чтобы принудительно запустить триггер, но некоторые таблицы содержат миллионы записей и растут, и это может занять 30 минут. , (и еще есть вакуум).

Есть ли какой-нибудь лучший способ вызвать его или какой-нибудь способ написать функцию, которая будет работать либо с входными данными, переданными внутрь, либо в NEWзависимости от контекста вызова? Я неохотно держу две разные функции рядом, так как я видел слишком много раз, когда одна обновляется, а другая нет.

Джо
источник
Я знал, как запустить триггер ... Я спросил, есть ли хороший способ.
Джо

Ответы:

19

Это можно сделать, используя следующий шаблон:

CREATE TABLE tablename ( ... );

/* for direct invocation */
CREATE FUNCTION propagate_data(newrow tablename) RETURNS void
LANGUAGE plpgsql
AS $$
BEGIN
    INSERT INTO other_table VALUES (newrow.a, newrow.b, ...);
END:
$$;

/* trigger function wrapper */
CREATE FUNCTION propagate_data_trg() RETURNS trigger
LANGUAGE plpgsql
AS $$
BEGIN
    PERFORM propagate_data(NEW);
END;
$$;

CREATE TRIGGER propagate_data AFTER INSERT ON tablename FOR EACH ROW
    EXECUTE PROCEDURE propagate_data_trg();
Питер Айзентраут
источник
Дох ... Я думал об этом задом наперед (пытаясь сделать функцию триггера вызываемой процедурой, а не наоборот).
Джо
1
Когда я действительно это сделал, я понял, что «строка» - зарезервированное слово, поэтому я исправил пример, чтобы другие не потратили так много времени на отладку.
Джо
1
Я действительно должен был следить несколько лет назад. Мне потребовалось некоторое время, прежде чем мне удалось заставить все работать в моей системе ... и этот метод работает, но производительность была ужасна. (это заняло от 30 минут до более чем одного дня).
Джо