SuperAPI AI 工具集

postgres-syntax-upsert-merge

数据与分析

查看项目

更新于 10-15 22:18

技能介绍

用途:在编写幂等插入、多动作数据同步,或从 MySQL INSERT ... ON DUPLICATE KEY UPDATE、SQL Server MERGE 迁移时,选择并正确书写 PostgreSQL 的 UPSERT 与 MERGE。也用于排查 INSERT 本应做 upsert 却报 23505 unique_violation,以及 MERGE 报 21000 基数冲突的错误。

主要能力:区分两种幂等写入原语。INSERT ... ON CONFLICT(9.5+)针对单一冲突目标、单一动作(DO NOTHING 或 DO UPDATE),是默认选择;MERGE(15+)支持对来源关系做多分支同步,多个 WHEN MATCHED / WHEN NOT MATCHED 分支各自 INSERT / UPDATE / DELETE / DO NOTHING,17 版新增 RETURNING、merge_action() 与 WHEN NOT MATCHED BY SOURCE。

关键规则:冲突目标必须对应已有的 UNIQUE 或 PRIMARY KEY(不可延迟)索引,可用列列表或 ON CONSTRAINT 名称指定;部分唯一索引需让 WHERE 谓词与索引 WHERE 完全匹配。EXCLUDED 指向拟插入行,目标表名指向现有行;RETURNING 只返回实际插入或更新的行,跳过 DO NOTHING。ON CONFLICT 不能用排除约束作仲裁。MERGE 的 ON 条件必须保证每个目标行至多匹配一个来源行,否则报 21000,需先对来源去重;15–17 版不能对物化视图或外部表执行 MERGE。

示例:INSERT INTO users (id, email, name) VALUES (1, 'a@b.c', 'Alice') ON CONFLICT (id) DO UPDATE SET email = EXCLUDED.email, name = EXCLUDED.name; MERGE INTO users t USING new_users s ON t.id = s.id WHEN MATCHED THEN UPDATE SET email = s.email WHEN NOT MATCHED THEN INSERT (id, email) VALUES (s.id, s.email);

版式说明:UPSERT 自 9.5 起全版本可用;MERGE 15 引入,RETURNING 与 merge_action()、WHEN NOT MATCHED BY SOURCE、带 RULE 的可更新视图上的 MERGE 均为 17 新增。混合版本环境可统一用 INSERT ... ON CONFLICT。

限制与不适用:不用于 UPDATE ... FROM、无冲突处理的 INSERT ... SELECT、COPY 批量加载(见 postgres-impl-bulk-loading)及 FDW 写入。参考文件 methods.md、examples.md、anti-patterns.md 与官方文档(INSERT、MERGE、15.0 与 17.0 发布说明)在资料中给出。未提供内容:安装命令、收费与平台信息暂未提供。