Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Requêtes PostgreSQL Discussion :

Eviter la mise à jour de table complète par un trigger


Sujet :

Requêtes PostgreSQL

  1. #1
    Membre régulier
    Eviter la mise à jour de table complète par un trigger
    Bonjour,

    un extrait de la table log :

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    gid alti  numlog
    1   79.55 1
    2   79.65 2


    un extrait de la table us :

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    gid numlog numus sommet base alti_sommet alti_base
    1   1      1000  0      0.25 (79.55-0)   (79.55-0.25)
    2   1      1001  0.25   0.39 (79.55-0.25)(79.55-0.39)
    3   1      1002  0.39   0.59 (79.55-0.39) ...
    4   2      1000  0      0.15 (79.65-0)
    5   2      1001  0.15   0.40 (79.65-0.15)


    Avec un trigger sur us, je souhaite mettre à jour alti_sommet and alti_base avec le calcul entre ().

    J'ai crée :

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    create or replace function activite.calcul_alti_us()
    returns trigger as
    $body$
     BEGIN
      update us
     set (alti_base, alti_sommet) = (l.alti - base, l.alti-sommet) 
     from log l 
     where us.numlog = l.numlog ;
     return NEW ;
    END ;
    $body$
    language 'plpgsql' ;


    et le trigger :

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    CREATE TRIGGER trg_calcul_alti_us
    AFTER insert ON us
    FOR EACH ROW
    EXECUTE PROCEDURE activite.calcul_alti_us();


    Donc ca fonctionne pour toute la table, toujours ça.
    Mais je ne souhaite pas qu'à chaque insert dans log, toute la table us soit mise à jour.
    Et là je n'arrive pas à ne faire travailler le trigger uniquement sur les linges insérées soit sur le ou les numlog nouvellement insérés dans us.
    J'ai une mauvaise utilisation de NEW à priori.
    Des pistes ? Merci

  2. #2
    Membre averti
    Je suis peut-être aveugle mais... Vous n'utilisez tout simplement pas le NEW en fait, non ?

    Essayez, dans le where de votre update, de rajouter quelque chose comme "AND macolonne = NEW.macolonne"
    Ou alors si vous voulez changer une des valeurs avant l'insertion :

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    NEW.mavaleur := 'TOTO'


    Sinon je vous invite à lire la doc officielle :
    https://www.postgresql.org/docs/9.2/plpgsql-trigger.html

    Bisous bisous

  3. #3
    Membre régulier
    Oui, mauvaise journée hier.
    J'ai résolu le souci comme suit, ça peut servir :

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    create or replace function activite.calcul_alti_us()
    returns trigger as
    AS $BODY$
    BEGIN
     		IF (TG_OP IN ('INSERT', 'UPDATE')) THEN
    		NEW.altitoit = (select alti - NEW.proftoit 
    						from activite.geo g 
    						where NEW.gid_geo = g.gid );
    		NEW.altibase = (select alti - NEW.profbase
    						from activite.geo g 
    						where NEW.gid_geo = g.gid );
    		RETURN NEW ;
    	END IF ;
    END ;
    $BODY$;
    language 'plpgsql' ;


    et aussi changer le TRIGGER pour BEFORE, autant changer une valeur avant l'insertion plutôt que d'en insérer une et la changer ensuite.
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    CREATE TRIGGER trg_calcul_alti_us
        BEFORE INSERT OR UPDATE 
        ON activite.us
        FOR EACH ROW
        EXECUTE PROCEDURE activite.calcul_alti_us();


    Ainsi ne sont mis à jour que les enregistrements ajoutés et pas toute la table à chaque insertion.

###raw>template_hook.ano_emploi###