如何在 Postgresql 中获取结合 old.variablename 的列数据?

Posted

技术标签:

【中文标题】如何在 Postgresql 中获取结合 old.variablename 的列数据?【英文标题】:How to get column data combining old.variablename in Postgresql? 【发布时间】:2018-09-25 18:10:20 【问题描述】:

我正在尝试构建一个用于检索表主键列的审计触发器函数(适用于多个表)。例如,有一个表customers 以'customerid' 作为主键,还有一个表orders 以'orderid' 作为主键。

有了这个,我找到了触发函数的表的列/主键的名称,并将其存储在“prim”中。

prim :=(SELECT c.column_name
    FROM information_schema.key_column_usage AS c
    LEFT JOIN information_schema.table_constraints AS t
    ON t.constraint_name = c.constraint_name
    WHERE(t.table_name = TG_TABLE_NAME) AND t.constraint_type = 'PRIMARY 
KEY');

这确实有效。 Prim 的字面意思是“orderid”或“customerid”,具体取决于哪个表触发了该功能。现在,我想做的是获取我检索到的列的信息,并将其插入到审计表中。所以假设我从客户表中删除了一行,我想将该事件插入到审计表中。我尝试这样做:

INSERT INTO audit(columnname,dataincolumn,tablename)
VALUES(prim,old.prim,tg_table_name);

我知道它有很多问题,但我怎样才能得到我的输出:

COLUMN     DATAINCOLUMN    TABLE
--------------------------------
customersid    12     Customers
orderid        23     Orders

我收到以下错误:

ERROR:  record "old" has no field "prim"

【问题讨论】:

为什么不使用已经可用的触发器实现? here 或 here 或 here 【参考方案1】:

这有点棘手,但您可以使用动态 SQL 并将值转换为正确的类型。

假设您有一个bigint 变量val(或integer,取决于您的需要),您可以这样做:

EXECUTE format('SELECT (($1)::%I).%I', TG_TABLE_NAME, prim)
INTO val
USING OLD;

【讨论】:

以上是关于如何在 Postgresql 中获取结合 old.variablename 的列数据?的主要内容,如果未能解决你的问题,请参考以下文章

在删除触发postgreSQL之前检查列值

如何跟踪 PostgreSQL 中任何函数的变化

在 PostgreSQL 中结合 CTE 和 IN

如何在 Postgresql 中获取不同的值?

PostGreSQL 结合 Hibernate 在项目中的使用小结

如何在 Postgresql 交叉表中获取动态列数