我想请教下opengauss6.0的轻量版是否支持ON CONFLICT DO NOTHING,ON CONFLICT DO UPDATE语法,我看GaussDB的官方文档有说支持,但是OpenGauss的文档中没看到,测试发现不支持,如果是这样,这个考虑是为什么?经济利益吗?
结论先行:
openGauss 6.0(含轻量版)没有完整实现 PostgreSQL 的 ON CONFLICT DO NOTHING / DO UPDATE 语法。
目前能用的“Upsert”功能只有 MySQL 风格的 INSERT … ON DUPLICATE KEY UPDATE …,而且该写法不支持 DO NOTHING 子句,也不支持 RETURNING 。因此,如果你直接写 ON CONFLICT 会报语法错误,与 GaussDB 文档里提到的“支持”并不同步。
- 官方现状
- 内核基于早期 PostgreSQL 9.2.4,当时还没有
ON CONFLICT。 - 6.x 仍沿用 MySQL 风格 的
ON DUPLICATE KEY UPDATE,可完成“冲突即更新”,但:- 没有
DO NOTHING分支; - 不支持
RETURNING子句; - 列存表、外表、内存表均不可用 。
- 没有
- 论坛与 issue 里已多次确认 6.0 轻量版同样不支持
ON CONFLICT。
- 可用替代方案
① 纯 SQL 方案
先尝试 INSERT,捕获唯一键冲突后再 UPDATE(需客户端跑两条语句,或包在存储过程/PLSQL 里)。
② 使用 MERGE INTO(6.0 已支持)
一条语句完成“匹配更新 / 不匹配插入”,语法示例:
MERGE INTO target t
USING (VALUES (?, ?, ?)) AS s(pk_col, col1, col2)
ON t.pk_col = s.pk_col
WHEN MATCHED THEN UPDATE SET col1 = s.col1, col2 = s.col2
WHEN NOT MATCHED THEN INSERT (pk_col, col1, col2) VALUES (s.pk_col, s.col1, s.col2);
支持 RETURNING,也支持多行冲突(需打开 behavior_compat_options='merge_update_multi')。
缺点:写法比 ON CONFLICT 冗长,且性能略低。
- 版本展望
openGauss 社区已把“兼容 PostgreSQLON CONFLICT”列入路线图,5.1/6.1 预览分支里开始回合代码,但正式合入要到 7.0 LTS(预计 2026 Q1)。轻量版通常会同步主干,因此 6.0 无望后端合入。
- 结论与建议
- 6.0 轻量版 现在只能用
ON DUPLICATE KEY UPDATE(无DO NOTHING,无RETURNING)- 或者
MERGE INTO(功能最全,推荐)。
- 若业务强依赖
ON CONFLICT语法,只能等待 7.0 正式版 或改用原生 PostgreSQL / 其他已支持的数据库。
谢谢,使用MERGE INTO重写了相关逻辑。