我不得不重新安装我的Hyper-V Windows服务器,因此我对PostgreSQL数据库进行了架构备份。
之后,我导入了架构备份。表面上看起来一切都很好。所有表格,函数,触发器和序列都在那里。除了由于某种原因触发功能不再做任何事情。
我有两个触发器,这是两个中的一个。
CREATE TRIGGER t_update_modified
AFTER UPDATE
ON queue
FOR EACH ROW
EXECUTE PROCEDURE update_modified();
CREATE OR REPLACE FUNCTION update_modified()
RETURNS trigger AS
$BODY$BEGIN
NEW.modified = now();
Return NEW;
END;$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
ALTER FUNCTION update_modified()
OWNER TO postgres;
GRANT EXECUTE ON FUNCTION update_modified() TO postgres;
REVOKE ALL ON FUNCTION update_modified() FROM public;
我在代码中添加RAISE WARNING
语句来检查函数是否实际执行以及它们走了多远,我确认函数实际上已执行并且它们一直执行到{{1}声明。
我还添加了RETURN
语句来捕获可能引发的异常,但是没有发生这样的事情。
上面的函数应该更新修改列的时间戳,但没有任何反应。我的两个触发器函数都用于处理旧虚拟机。 EXCEPTION
用户拥有相关表的所有权限,并具有触发器功能的执行权限。
这是第二次触发:
postgres
与之前一样, CREATE TRIGGER t_new_task
AFTER INSERT OR UPDATE OF status
ON queue
FOR EACH ROW
EXECUTE PROCEDURE new_task();
CREATE OR REPLACE FUNCTION new_task()
RETURNS trigger AS
$BODY$BEGIN
NOTIFY newtask;
RETURN NULL;
END;$BODY$
LANGUAGE plpgsql VOLATILE LEAKPROOF
COST 100;
ALTER FUNCTION new_task()
OWNER TO postgres;
GRANT EXECUTE ON FUNCTION new_task() TO postgres;
GRANT EXECUTE ON FUNCTION new_task() TO public;
什么都不做。没有连接的客户端收到任何通知。这也适用于旧虚拟机。
除非我向其添加NOTIFY
语句,否则与触发器函数无关的任何内容都会记录到日志文件中。
我在使用触发器之前从未遇到过这种问题。有没有人知道这里发生了什么?
我也重新创建了这些触发器,但这也没有解决问题。
更新:我创建了一个新数据库,仅用于测试触发器。 Trigger也没有在那里工作,所以这个问题正在影响整个PostgreSQL服务器。我准备好把头发拉出来。
更新2:重新安装PostgreSQL服务器并删除其数据。触发器仍无法正常工作。
答案 0 :(得分:2)
使用BEFORE触发器。在AFTER触发器中,修改行值为时已晚。 如果您认为它之前有用并且这是环境问题,那么您很可能会在某些时候解释结果,因为(正如您在更新中提到的那样),这是一般性的事情。
以下是手册中提到的内容 http://www.postgresql.org/docs/current/static/trigger-definition.html
对于在a之后触发的行级触发器,将忽略返回值 操作,所以他们可以返回NULL。
BEFORE / AFTER的更完整的比较在以下几段之后:
通常,行级BEFORE触发器用于检查或 修改将要插入或更新的数据。例如,a BEFORE触发器可用于将当前时间插入到 timestamp列,或检查行的两个元素是什么 是一致的。行级AFTER触发器最明智地用于 将更新传播到其他表,或进行一致性检查 对其他桌子。这种分工的原因是: AFTER触发器可以确定它正在查看行的最终值, 虽然BEFORE触发器不能;可能还有其他BEFORE触发器 在它之后开火。如果您没有特定的理由进行触发 之前或之后,BEFORE案例更有效率,因为 有关操作的信息不必保存到结束 声明