使用 postgreSQL 触发器获取唯一更新的字段?

Say*_*akh 4 postgresql audit

有没有办法使用可以从记录中获取唯一更新字段的触发器?我只是在测试审计跟踪日志,因此它可以在更新时将字段名称与其其他信息一起保存。我不想使用 IF 语句,因为我的表中可能有 200 多个字段。

joa*_*olo 6

If you are using the latest versions of PostgreSQL, you can use the JSON(B) functions and operators to your advantage. Although this is not (yet) a full solution, check to see if it mimics what you're trying to achieve:

-- The 'new' and 'old' entries will simulate the 'old' and 'new' 
-- values for a row that you can use in a trigger function
WITH 
new(id, changed_column, integer_changed_column, not_changed,
   array_changed_column, changed_null) AS
(
    VALUES (12, text 'Value', 1234, text 'unchanged', 
        array [1, 2], cast(null as text))
),
old(id, changed_column, integer_changed_column, not_changed,
    array_changed_column, changed_null) AS
(
    VALUES (12, text 'New value', 1235, text 'unchanged', 
        array [1, 3], text 'not-null')
)

-- And we get a setof records with the changes
SELECT
    *
FROM
    (
    SELECT
        column_name, 
        (row_to_json(new)->column_name #>> '{}') AS new_value, 
        (row_to_json(old)->column_name #>> '{}') AS old_value
    FROM
        new, old, (
        SELECT
            json_object_keys(row_to_json(new)) AS column_name
        FROM
            new
        ) AS cc
    ) AS s0
WHERE
    new_value IS DISTINCT FROM old_value
ORDER BY
    column_name ;
Run Code Online (Sandbox Code Playgroud)

The result that you'll get shows you all the updated columns (=fields). I have assumed that more than one can be updated at once:

 column_name             | old_value | new_value
 ------------------------+-----------+-----------
 array_changed_column    | [1,2]     | [1,3] 
 changed_column          | Value     | New value 
 changed_null            |           | not-null 
 integer_changed_column  | 1234      | 1235 
Run Code Online (Sandbox Code Playgroud)

注意:所有值都转换为文本,因为它是所有其他值都可以转换为的类型。