我需要写入插入或更新触发器,但是在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。
答案 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('电子邮件无法更改'); } } }