web-dev-qa-db-fra.com

Postgres insert ou update trigger QUAND condition (ancienne)

J'ai besoin d'écrire un déclencheur d'insertion ou de mise à jour, mais avec la condition QUAND comparer les anciennes et les nouvelles lignes.

Selon la documentation, OLD est nul pour l'opération d'insertion. Comment puis-je utiliser OLD en condition WHEN pour les déclencheurs INSERT AND UPDATE?

Exemple de déclencheur:

CREATE TRIGGER mytrigger
    BEFORE INSERT OR UPDATE ON "mytable"
    FOR EACH ROW 
    WHEN (NEW.score > 0 AND OLD.score <> NEW.score)
    EXECUTE PROCEDURE mytrigger();

mais pour l'insertion, OLD est nul.

Option A:

Vous pouvez modifier le code afin que les conditions soient dans la fonction de déclenchement plutôt que dans le déclencheur lui-même. Avec cette approche, OLD ne sera utilisé que dans le UPDATE.

Déclencheur:

CREATE TRIGGER mytrigger
    BEFORE INSERT OR UPDATE ON "mytable"
    FOR EACH ROW 
    EXECUTE PROCEDURE mytrigger();

Fonction de déclenchement:

CREATE OR REPLACE FUNCTION mytrigger()
  RETURNS trigger AS
$BODY$
begin
if NEW.score > 0 then
     --code for Insert
     if  (TG_OP = 'INSERT') then
           YOUR CODE
     end if;

     --code for update
     if  (TG_OP = 'UPDATE') then
           if OLD.score <> NEW.score then  -- (if score can be null see @voytech comment to this post)
              YOUR CODE
           end if;
     end if;
end if;
return new;
end;
$BODY$
  LANGUAGE plpgsql VOLATILE

Option B:

Comme Thilo l'a suggéré, écrivez deux déclencheurs qui partagent la même fonction de déclencheur.

Déclencheurs:

CREATE TRIGGER mytrigger1
    BEFORE INSERT ON "mytable"
    FOR EACH ROW 
    WHEN NEW.score > 0
    EXECUTE PROCEDURE mytrigger();


CREATE TRIGGER mytrigger2
    BEFORE UPDATE ON "mytable"
    FOR EACH ROW 
    WHEN (NEW.score > 0 AND OLD.score <> NEW.score)
    EXECUTE PROCEDURE mytrigger();

Fonction de déclenchement:

CREATE OR REPLACE FUNCTION mytrigger()
  RETURNS trigger AS
$BODY$
begin
      YOUR CODE
return new;
end;
$BODY$
  LANGUAGE plpgsql VOLATILE
18
Elad