Postgres插入或更新触发器WHEN条件(旧)

时间:2016-03-16 07:41:29

标签: postgresql triggers

我需要写入插入或更新触发器,但是在WHEN条件下使用比较OLD和NEW行。

根据文档,插入操作的OLD为null。如何在INSERT和UPDATE触发器的WHEN条件下使用OLD?

示例触发器:

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

但是对于插入OLD为null。

2 个答案:

答案 0 :(得分:9)

选项A:

您可以更改代码,以便条件位于触发器功能中,而不是触发器本身。使用此方法时,OLD将仅用于UPDATE

触发:

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

触发功能:

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

选项B:

正如Thilo建议写两个共享相同触发函数的触发器。

触发器:

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

触发功能:

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

答案 1 :(得分:-1)

Trigger.oldMap.keySet();将在Trigger.oldMap中给出Id的存在。 它是所有Id的集合类型集合。 看看下面的例子,每次更改触发事件中的DML事件并查看调试日志。 您将了解哪个触发器上下文变量可用于哪个DML事件。

CREATE TRIGGER Email_Check_On_Contact              更新前{  oldMap = new Map();  o = trigger.oldMap;  for(联系newcont:trigger.new)              {  if(newcont.Email!= o.get(newcont.Id).Email)                       {                           newcont.Email.addError('电子邮件无法更改');                       }               }                            }