Czy istnieje dobry sposób uruchomienia wyzwalacza dla każdego rekordu w tabeli postgres?

22

Mam system, w którym nie mogę kontrolować projektu niektórych tabel (replikowanych przez Slony-I), więc mam szereg tego, co nazywamy „tabelami cieni”, w których wydobywam niektóre informacje z replikowanych tabel i przechowuj go w przetworzonej formie, której potrzebuję, jednocześnie usuwając rekordy, które chcę zignorować.

W tej chwili po skonfigurowaniu nowej repliki uruchamiam aktualizację i ustawiam wartość z powrotem do siebie (np. UPDATE tablename SET field=field), Aby wymusić uruchomienie wyzwalacza, ale niektóre tabele mają miliony rekordów i rosną i może to potrwać 30 minut . (a potem jest też próżnia).

Czy jest jakiś lepszy sposób, aby go wyzwolić lub napisać funkcję, która będzie działała z wejściem przekazanym lub NEWzależnym od kontekstu wywołania? Niechętnie trzymam przy sobie dwie różne funkcje, ponieważ widziałem zbyt wiele razy, gdy jedna jest aktualizowana, a nie druga.

Joe
źródło
Wiedziałem, jak uruchomić spust ... Zapytałem, czy istnieje dobry sposób.
Joe

Odpowiedzi:

19

Można to zrobić za pomocą następującego szablonu:

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();
Peter Eisentraut
źródło
Doh ... Myślałem o tym wstecz (próbując ustawić funkcję wyzwalacza na podstawie procedury, a nie odwrotnie).
Joe
1
Kiedy to zrobiłem, zdałem sobie sprawę, że słowo „wiersz” jest słowem zastrzeżonym, więc poprawiłem przykład, aby inni nie spędzali tak długo na debugowaniu.
Joe
1
Naprawdę powinienem był śledzić lata temu. Minęło trochę czasu, zanim udało mi się sprawić, że wszystko działało w moim systemie ... i ta metoda działa, ale wydajność była boska. (trwało to od 30 minut do ponad jednego dnia).
Joe