PostgreSQL触发器无法正常工作 - 既不是BEFORE也不是AFTER DELETE

kin*_*nic 7 postgresql triggers plpgsql

我刚刚离开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();
Run Code Online (Sandbox Code Playgroud)

我的问题是双重的:

  1. 如果我如上所述使用AFTER DELETE,则该行将被删除,但update语句不会更新"workflow"表中的字段.

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

任何人都可以建议吗?

Erw*_*ter 16

问题2:

您的触发器功能以:

RETURN NULL;
Run Code Online (Sandbox Code Playgroud)

这样就可以跳过触发事件的执行.关于触发程序的文档:

发射行级触发器BEFORE可以返回null信号触发经理跳过操作的休息此行(即,随后的触发器不会被触发,以及INSERT/ UPDATE/ DELETE没有此行发生).

您需要将其替换为:

RETURN OLD;
Run Code Online (Sandbox Code Playgroud)

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

在的情况下,才触发DELETE,返回的值没有直接的影响,但它必须是一个非空允许触发行动继续进行.请注意,触发器中NEW为null DELETE,因此返回通常是不合理的.触发器中通常的习惯DELETE是返回OLD.

大胆强调我的.

问题1

我认为你的触发器和触发器功能不应该起作用的原因AFTER DELETE.不言而喻process_id,表中必须存在具有匹配的行workflow.