【问题标题】:postgreSQL log changed columnpostgreSQL 日志更改列
【发布时间】:2020-01-12 22:05:16
【问题描述】:

我正在使用触发器记录所有 UPDATEINSERT 操作,但我的表有很多列,我想记录我更新了哪一列或插入及其新旧值。以下是我要实现的目标的演示:

big table                   
-------------------------   
id       |feild_1   | field_2| field_3 .....          
-----------------------------------------------     
usr1     |old_value1|   
usr2     |old_value2|  

假设我将 usr1 filed_1 中的值更改为“new_value1”。我想查看我的更改历史记录:

change history
------------------------- 
id       |field_changed  | old_value | new_value |        
----------------------------------------------------------- 
usr1     |field_1        |old_value_1|new_value_1|  

难点在于实现我修改的列名。 我使用的当前触发函数是从https://stackoverflow.com/a/49872254/5749562修改而来的。如下所示:

CREATE FUNCTION change_trigger() RETURNS trigger AS $$
       BEGIN
         IF TG_OP = 'INSERT'
         THEN INSERT INTO change_history (
                id, old_value, new_value
              ) VALUES (
                OLD.id, row_to_json(OLD), row_to_json(NEW)
              );
           RETURN NEW;
         ELSIF  TG_OP = 'UPDATE'
         THEN
           INSERT INTO change_history (
             id, old_value, new_value
           )
           VALUES (OLD.id, row_to_json(OLD), row_to_json(NEW));
           RETURN NEW;
         END IF;
       END;
$$ LANGUAGE 'plpgsql' SECURITY DEFINER;

如您所见,所有列都在更改期间记录,这对于大表来说信息量不大。如何修改触发功能?

【问题讨论】:

标签: postgresql logging triggers


【解决方案1】:

PostgreSQL 总是更新整行,无法在触发器中确定UPDATE 语句的SET 子句中列出了哪些列。

您可以做的最好的事情是通过测试找出哪些列被UPDATE 更改了

IF OLD.col IS DISTINCT FROM NEW.col

【讨论】:

  • 我宁愿建议IF OLD.col IS DISTINCT FROM NEW.col。列列表可以查询pg_attribute(postgresql.org/docs/current/catalog-pg-attribute.html)
  • 这是否意味着我需要遍历所有列并获取触发器函数中 NEW 和 OLD 具有不同值的列?如果是这样,列迭代和列名检索的代码是什么样的?任何示例将不胜感激。
  • 您可以使用information_schema.columns 进行自省。 This answer 展示了如何使用动态 SQL 从使用动态 SQL 的 NEW 中提取列。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-24
  • 1970-01-01
  • 2020-02-16
  • 1970-01-01
相关资源
最近更新 更多