Postgresql 从通用触发器中的不同列获取值

Postgresql 从通用触发器中的不同列获取值,postgresql,triggers,plpgsql,dynamic-sql,Postgresql,Triggers,Plpgsql,Dynamic Sql,我是PostgreSQL的新手,我发现了一个完全符合我目的的触发器,除了一件小事。触发器非常通用,可以跨不同的表运行,并记录不同的字段更改。我找到了 我现在需要做的是测试一个特定字段,该字段随着触发触发器的表的更改而更改。我考虑使用substr,因为所有列都将具有相同的名称格式,例如XXX\u cust\u no,但XXX可以更改为2或4个字符。我需要在XXX\u cust\u no字段中记录写入历史记录/审核表的每条记录的值。我不想使用一堆IF/ELSE语句来实现这一点 触发器现在工作时记录表

我是PostgreSQL的新手,我发现了一个完全符合我目的的触发器,除了一件小事。触发器非常通用,可以跨不同的表运行,并记录不同的字段更改。我找到了

我现在需要做的是测试一个特定字段,该字段随着触发触发器的表的更改而更改。我考虑使用
substr
,因为所有列都将具有相同的名称格式,例如
XXX\u cust\u no
,但XXX可以更改为2或4个字符。我需要在
XXX\u cust\u no
字段中记录写入历史记录/审核表的每条记录的值。我不想使用一堆IF/
ELSE
语句来实现这一点


触发器现在工作时记录
表名
列名
旧值
新值
。但是,我还需要记录更改的记录的
XXX\u cust\u no

基本上,动态列名需要动态SQL<代码>格式化有助于格式化DML命令。用
USING
子句传递
NEW
OLD
中的值

鉴于这些表格:

CREATE TABLE tbl (
  t_id serial PRIMARY KEY
 ,abc_cust_no text
);

CREATE TABLE log (
  id          int
 ,table_name  text
 ,column_name text
 ,old_value   text
 ,new_value   text
);
它可以这样工作:

CREATE OR REPLACE FUNCTION trg_demo()
  RETURNS TRIGGER AS
$func$
BEGIN

EXECUTE format('
   INSERT INTO log(id, table_name, column_name, old_value, new_value)
   SELECT ($2).t_id
         , $3
         , $4
         ,($1).%1$I
         ,($2).%1$I', TG_ARGV[0])
USING OLD, NEW, TG_RELNAME, TG_ARGV[0];

RETURN NEW;

END
$func$ LANGUAGE plpgsql;

CREATE TRIGGER demo
BEFORE UPDATE ON tbl
FOR EACH ROW EXECUTE PROCEDURE trg_demo('abc_cust_no'); -- col name here.

有关dba.SE的回答:


也许您需要这个触发器:IIRC您现在可以使用
EXECUTE
OLD
NEW
动态提取字段。