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

标签 postgresql triggers plpgsql dynamic-sql

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

我现在需要做的是测试特定字段,该字段会随着触发器触发的表的变化而变化。我想到使用 substr 因为所有列都将具有相同的名称格式,例如XXX_cust_no 但 XXX 可以更改为 2 或 4 个字符。我需要将写入history_/audit表的每条记录的值记录在XXX_cust_no字段中。我不想使用一堆 IF/ELSE 语句来完成此任务。

触发器现在的工作方式会记录table_namecolumn_nameold_valuenew_value。但是,我还需要记录已更改的记录的 XXX_cust_no

最佳答案

基本上,您需要动态 SQL 来获取动态列名称。 format 有助于格式化 DML 命令。使用 USING 子句传递 NEWOLD 中的值。

鉴于这些表格:

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.

SQL Fiddle.

dba.SE 上的相关答案:

List of special variables visible in plpgsql trigger functions in the manual.

关于postgresql - 从通用触发器中的不同列获取值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26354558/

相关文章:

sql - 如何按日期创建 SQL 多次计数计数查询?

sql-server - SQL事务死锁

使用自定义类型时 PostgreSQL 仅返回一行

Jquery如何取消触发函数

mysql - 如何在 MySQL 上的另一个 if 子句中创建一个 if 子句

SQL合并行

sql - 从 plpgsql 函数返回一个选择

python - Django-dbbackup : how to change backup file extension?

sql - postgres正则表达式国际电话代码匹配

Apache Ambari 过时的 PID 错误