PostgreSQL触发器停止工作

时间:2015-11-16 13:18:48

标签: postgresql

我不得不重新安装我的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服务器并删除其数据。触发器仍无法正常工作。

1 个答案:

答案 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案例更有效率,因为   有关操作的信息不必保存到结束   声明