如何修改触发器以更新 PostgreSQL 中的单个属性

Posted

技术标签:

【中文标题】如何修改触发器以更新 PostgreSQL 中的单个属性【英文标题】:How to modify Trigger to update a single attribute in PostgreSQL 【发布时间】:2017-01-09 04:06:53 【问题描述】:

这是我的示例表。

CREATE TABLE employee_test(
idTst SERIAL PRIMARY KEY, 
monthDownload VARCHAR(6),
changeDate DATE);

我正在尝试创建一个函数和触发器,该函数和触发器将在更新 monthDownload 属性时使用当前日期更新 changeDate 属性。 我拥有的功能可以解决一个问题。它更新所有记录,而不是更新的记录。

 CREATE OR REPLACE FUNCTION downloadMonthChange() 
 RETURNS TRIGGER AS 
 $$
 BEGIN
 IF NEW.monthDownload <> OLD.monthDownload THEN
 UPDATE employee_test
 SET changeDate = current_date
 where OLD.idTst = NEW.idTst;
 END IF;
 RETURN NEW;
 END;
 $$ 
 Language plpgsql;

触发器

Create TRIGGER dataTest
AFTER UPDATE
ON employee_test
FOR EACH ROW
EXECUTE PROCEDURE downloadMonthChange();

当我执行以下更新语句时:

UPDATE  employee_test SET  monthDownload = 'oct12'
WHERE idTst = 1;

所有 changeDate 行都使用当前日期进行更新。 有没有办法让只有一行更改记录来更新当前日期。

【问题讨论】:

【参考方案1】:

如果您使用before 触发器,您可以直接写入NEW

 CREATE OR REPLACE FUNCTION downloadMonthChange() 
 RETURNS TRIGGER AS 
 $$
 BEGIN
 IF NEW.monthDownload <> OLD.monthDownload THEN
   NEW.changeDate = current_date;
 END IF;
 RETURN NEW;
 END;
 $$ 
 Language plpgsql;

当您必须使用after 触发器时,另一个选项是在where 子句中包含主键。您似乎正在尝试执行此操作,但查询中有一个虚假的 OLD。因为 where 子句只查看负责触发调用的记录,而不限制要更新的记录。

 IF NEW.monthDownload <> OLD.monthDownload THEN
 UPDATE employee_test
 SET changeDate = current_date
 where idTst = NEW.idTst;

【讨论】:

以上是关于如何修改触发器以更新 PostgreSQL 中的单个属性的主要内容,如果未能解决你的问题,请参考以下文章

PostgreSQL中实现更新默认值

postgresql 上的更新类型

如何在 PostgreSQL 中临时禁用触发器?

PostgreSQL 触发器不起作用 - 既不是 BEFORE 也不是 AFTER DELETE

postgresql无法创建触发器

单行列字段的 Postgresql 触发器