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



>我需要写入插入或更新触发器,但使用 WHEN 条件比较旧行和新行。

根据文档,对于插入操作,OLD 为空。如何在 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 为空。

选项 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

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

    CREATE TRIGGER Email_Check_On_Contact
                 before update{
     oldMap<ID,Contact>=new Map<ID,Contact>();
     o = trigger.oldMap;
     for(Contact newcont: trigger.new)
     {
        if(newcont.Email != o.get(newcont.Id).Email)
        {
            newcont.Email.addError('Email cannot be changed');
        }
      }
   }

最新更新