【问题标题】:PostgreSQL trigger not working - neither BEFORE nor AFTER DELETEPostgreSQL 触发器不起作用 - 既不是 BEFORE 也不是 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();

我的问题有两个:

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

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

谁能给点建议?

【问题讨论】:

    标签: postgresql triggers plpgsql


    【解决方案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 行为并不十分熟悉。
    猜你喜欢
    • 1970-01-01
    • 2014-07-18
    • 2020-08-08
    • 1970-01-01
    • 2023-03-11
    • 2013-12-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多