>我需要写入插入或更新触发器,但使用 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');
}
}
}