-- 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 ;
您将获得的结果显示所有更新的列 (=fields)。我假设一次可以更新多个:
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
如果您使用的是最新版本的 PostgreSQL,则可以使用 JSON(B) 函数和运算符来发挥您的优势。尽管这(还)不是一个完整的解决方案,但请检查它是否模仿了您想要实现的目标:
您将获得的结果显示所有更新的列 (=fields)。我假设一次可以更新多个:
注意:所有值都转换为文本,因为它是所有其他值都可以转换为的类型。
另一种方法是利用 PostgreSQL 最新版本中的 JSON/JSONB 函数。它的优点是可以处理任何可以转换为 JSON 对象(行或任何其他结构化数据)的东西,而且您甚至不需要知道记录类型。
请参阅我的原始StackOverflow 帖子以及适当的示例。