web-dev-qa-db-fra.com

Y a-t-il un bon moyen d'exécuter un déclencheur pour chaque enregistrement dans une table Postgres?

J'ai un système dans lequel je ne peux pas contrôler la conception de certaines tables (répliquées via Slony-i), et j'ai donc une série de ce que nous appelons "tables shadales", où j'élaisse certaines informations sur les tables répliquées et stockez-le dans la forme traitée dont j'ai besoin, tout en éliminant les enregistrements que je veux ignorer.

À l'heure actuelle, après avoir configuré une nouvelle réplique, je exécutore une mise à jour et définit une valeur de retour sur elle-même (par exemple, UPDATE tablename SET field=field) Pour forcer la gâchette à courir, mais certaines des tables sont des millions d'enregistrements et de grandir, et cela peut prendre 30 minutes. (Et puis il y a le vaccot, aussi).

Existe-t-il un meilleur moyen de le déclencher, ou d'une manière d'écrire une fonction de telle sorte qu'il fonctionnera avec l'une des entrées transmises ou NEW selon le contexte de l'appel? Je suis réticent à conserver deux fonctions différentes, comme je l'ai vu trop de fois où l'on se met à jour, et pas l'autre.

23
Joe

Cela peut être fait en utilisant le modèle suivant:

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();
19
Peter Eisentraut