修改OLD以在PostgreSQL触发函数中由DELETE返回

时间:2019-04-03 10:41:32

标签: sql postgresql triggers sql-function postgresql-triggers

我在postgresql中有一个触发函数,它将在INSERT,UPDATE和DELETE操作的审计表中插入行。在我的表中,有一列名为 audit_id ,我需要在此字段中写入插入的 audit 行的ID。这是我的功能

CREATE OR REPLACE FUNCTION my_audit_trigger()
 RETURNS trigger LANGUAGE plpgsql
AS $function$
declare
  audit_pk bigint;
begin
IF TG_OP = 'INSERT'
THEN
INSERT INTO audit.table_audit (rel_id, table_name, operation, after)
VALUES (TG_RELID, TG_TABLE_NAME, TG_OP, to_jsonb(NEW)) returning id into audit_pk;
 NEW.audit_id := audit_pk;
RETURN NEW;
ELSIF TG_OP = 'UPDATE'
THEN
IF NEW != OLD THEN
 INSERT INTO audit.table_audit (rel_id, table_name, operation, before, after)
VALUES (TG_RELID, TG_TABLE_NAME, TG_OP, to_jsonb(OLD), to_jsonb(NEW)) returning id into audit_pk;
END IF;
 NEW.audit_id := audit_pk;
RETURN NEW;
ELSIF TG_OP = 'DELETE'
THEN
INSERT INTO audit.table_audit (rel_id, table_name, operation, before)
VALUES (TG_RELID, TG_TABLE_NAME, TG_OP, to_jsonb(OLD)) returning id into audit_pk;
OLD.audit_id := audit_pk;
RETURN OLD;
END IF;
end;
$function$;

结果是,在插入或更新表行时,我取回了相应操作的审核ID,但是在运行DELETE命令时,我取回了先前操作而不是DELETE本身的审核ID。所以我想问题出在OLD.audit_id := audit_pk;

更具体地说,我运行例如INSERT INTO table VALUES (this, that) RETURNING audit_id,然后获得INSERT操作的audit_id。

之后,在运行DELETE FROM table WHERE id = sth RETURNING audit_id时,我得到INSERT操作而不是DELETE的audit_id。

感谢您的帮助,谢谢。

P.S。这就是我创建触发器的方式

CREATE TRIGGER table_trigger
BEFORE INSERT OR UPDATE OR DELETE
ON table
FOR EACH ROW
EXECUTE PROCEDURE my_audit_trigger();           

1 个答案:

答案 0 :(得分:0)

我有类似的问题。似乎PG现在不支持OLD的修改,但是,此功能可能会包含在TODO列表中。

当前,您只能针对INSERT和UPDATE语句修改 NEW

有关详细信息,请查看以下邮件线程:Does 'instead of delete' trigger support modification of OLD