Existe-t-il un bon moyen d'exécuter un déclencheur pour chaque enregistrement d'une table postgres?


22

J'ai un système où 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 des «tables fantômes», où j'extrais des informations des tables répliquées et le stocker dans le formulaire traité dont j'ai besoin, tout en supprimant les enregistrements que je veux ignorer.

En ce moment, après avoir configuré une nouvelle réplique, j'exécute une mise à jour et je me redéfinis une valeur (par exemple, UPDATE tablename SET field=field) pour forcer l'exécution du déclencheur, mais certaines tables sont des millions d'enregistrements, et en croissance, et cela peut prendre 30 minutes . (et puis il y a aussi le vide).

Y a-t-il un meilleur moyen de le déclencher, ou un moyen d'écrire une fonction de telle sorte qu'elle fonctionne avec une entrée passée ou NEWselon le contexte d'appel? Je suis réticent à garder deux fonctions différentes, car j'ai vu trop de fois où l'une est mise à jour et pas l'autre.


Je savais comment lancer un déclencheur ... J'ai demandé s'il y avait un bon moyen.
Joe

Réponses:


19

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();

Doh ... J'y pensais à l'envers (en essayant de rendre la fonction de déclenchement appelable par une procédure, pas de visas-versa).
Joe

1
Quand je l'ai fait, j'ai réalisé que «rangée» était un mot réservé, j'ai donc corrigé l'exemple pour que les autres ne passent pas autant de temps à déboguer.
Joe

1
J'aurais vraiment dû faire un suivi il y a des années. Il m'a fallu un peu de temps avant de réussir à tout faire fonctionner dans mon système ... et cette méthode fonctionne, mais les performances étaient horribles. (il est passé de 30 min à plus d'une journée pour terminer).
Joe
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.