gpt4 book ai didi

PostgreSQL 触发器停止工作

转载 作者:行者123 更新时间:2023-11-29 12:59:45 28 4
gpt4 key购买 nike

我不得不重新安装我的 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 语句来检查函数是否真的被执行了以及它们执行了多远,我确认函数确实被执行了并且它们一直执行到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什么都不做。没有连接的客户端收到任何通知。这也曾经在旧虚拟机上工作。

与触发器函数相关的任何内容都不会记录到日志文件中,除非我向它们添加 RAISE WARNING 语句。

在使用触发器之前,我从未遇到过此类问题。有人知道这里发生了什么吗?

我也重新创建了这些触发器,但这也没有解决问题。

更新:我创建了一个新的数据库来测试触发器。触发器在那里也不起作用,所以这个问题影响了整个 PostgreSQL 服务器。我正准备拔头发。

更新 2:重新安装 PostgreSQL 服务器并删除其数据。触发器仍然不起作用。

最佳答案

使用 BEFORE 触发器。在 AFTER 触发器中,修改行值为时已晚。如果您认为它以前有效并且是环境问题,那么您很可能在某些时候混淆了结果的解释,因为(正如您在更新中提到的)这是普遍现象。

这是手册中提到的方式,在 http://www.postgresql.org/docs/current/static/trigger-definition.html

The return value is ignored for row-level triggers fired after an operation, and so they can return NULL.

更完整的 BEFORE/AFTER 比较如下:

Typically, row-level BEFORE triggers are used for checking or modifying the data that will be inserted or updated. For example, a BEFORE trigger might be used to insert the current time into a timestamp column, or to check that two elements of the row are consistent. Row-level AFTER triggers are most sensibly used to propagate the updates to other tables, or make consistency checks against other tables. The reason for this division of labor is that an AFTER trigger can be certain it is seeing the final value of the row, while a BEFORE trigger cannot; there might be other BEFORE triggers firing after it. If you have no specific reason to make a trigger BEFORE or AFTER, the BEFORE case is more efficient, since the information about the operation doesn't have to be saved until end of statement

关于PostgreSQL 触发器停止工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33736395/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com