You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PostgreSQL中能否用ROW类型变量简化ON CONFLICT DO UPDATE语句?

在PostgreSQL 14中实现ON CONFLICT时批量更新所有列的简化写法

PostgreSQL 14并不支持你尝试的SET (*) = ROW(_context.*)这种直接批量更新所有列的语法,但有两种简化方式能帮你实现需求,不用手动逐个枚举列名:

方案1:用表别名结合excluded虚拟行

这是最简洁的写法,直接利用PostgreSQL提供的excluded虚拟行(它代表原本要插入的那条数据),配合表别名就能一次性更新所有列:

INSERT INTO audit.etl_failed_execution_contexts AS efc
VALUES (_context.*)
ON CONFLICT (correlation_id) 
DO UPDATE SET 
  efc = excluded;

只要_context的结构和目标表完全匹配(列数、顺序、数据类型一致),这个写法就能正常工作。就算后续表结构新增了列,也不用修改这条语句,维护起来很省心。另外因为触发冲突的correlation_id在excluded和现有行里是同一个值,更新后不会有变化,不用担心破坏约束。

方案2:自动生成列列表(适合需要显式列的场景)

如果偏好显式列出列名,但不想手动输入所有字段,可以先查询系统表自动生成列列表:

SELECT string_agg(column_name, ', ') 
FROM information_schema.columns 
WHERE table_schema = 'audit' AND table_name = 'etl_failed_execution_contexts';

把查询结果复制到下面的语句里,就能用行构造函数批量更新:

INSERT INTO audit.etl_failed_execution_contexts
VALUES (_context.*)
ON CONFLICT (correlation_id) 
DO UPDATE SET 
  (col1, col2, col3, ...) = ROW(excluded.col1, excluded.col2, excluded.col3, ...);

这个写法需要每次表结构变更后重新生成列列表,适合对语法严谨性有要求的场景。

内容的提问来源于stack exchange,提问作者quickdraw

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 17:42:49