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

Posted

技术标签:

【中文标题】PostgreSQL 触发器不起作用 - 既不是 BEFORE 也不是 AFTER DELETE【英文标题】:PostgreSQL trigger not working - neither BEFORE nor AFTER DELETE 【发布时间】:2012-05-21 14:51:23 【问题描述】:

我刚刚放弃了 mysql 以支持 PostgreSQL,并且我有一个关于触发器的问题。如果删除了“流程”表中的行,则此触发器旨在更新“工作流程”表中的字段。

CREATE OR REPLACE FUNCTION fn_process_delete() RETURNS TRIGGER AS $$
BEGIN
    UPDATE workflow SET deleted_process_name = OLD.process_name
    WHERE process_id = OLD.process_id;
    RETURN NULL;
END;
$$ LANGUAGE plpgsql;

DROP TRIGGER IF EXISTS process_delete ON processes;
CREATE TRIGGER process_delete
AFTER DELETE ON processes
FOR EACH ROW 
EXECUTE PROCEDURE fn_process_delete();

我的问题有两个:

    如果我像上面那样使用 AFTER DELETE,该行将被删除,但更新语句不会更新“工作流”表中的字段。

    如果我使用 BEFORE DELETE,则进程表将根本不执行删除,并提供错误消息“此行没有唯一标识符”。

谁能给点建议?

【问题讨论】:

【参考方案1】:

问题2:

您的触发函数以:

结尾
RETURN NULL;

这样您就可以跳过触发事件的执行。 Per documentation on trigger procedures:

触发的行级触发器 BEFORE 可以返回 null 来表示触发器 经理跳过该行的其余操作(即, 随后的触发器不会被触发,INSERT/UPDATE/DELETE 会 此行不会出现)。

您需要将其替换为:

RETURN OLD;

让系统继续删除该行。原因如下:

对于DELETE上的before-trigger,返回值没有 直接效果,但它必须是 nonnull 以允许触发动作 继续。请注意 NEWDELETE 触发器中为空,因此返回 通常是不明智的。 DELETE 触发器中的常用习语是 返回OLD

我的大胆强调。

问题 1

我看不出为什么您的触发器和触发器函数不应该像 AFTER DELETE 那样工作。不用说,表workflow 中必须存在与process_id 匹配的行。

【讨论】:

太好了 - 谢谢!在 MySQL 之后,我对触发 RETURN 行为并不十分熟悉。

以上是关于PostgreSQL 触发器不起作用 - 既不是 BEFORE 也不是 AFTER DELETE的主要内容,如果未能解决你的问题,请参考以下文章

引发错误在 MySQL 触发器中不起作用

如何在 PostgreSQL 中复制函数

除非我触发我的连接回调两次,否则使用 strophe attach() 而不是 connect() 不起作用

为什么executeUpdate()函数不起作用?给出在正常项目而不是基于maven的项目中解决的步骤[重复]

PostgreSQL插入不起作用

SQLAlchemy 使用合并更新 PostgreSQL 数组不起作用