Чи є хороший спосіб запустити тригер для кожного запису в таблиці постгресів?


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 хв до більше дня).
Джо
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.