← 返回题目列表

Oracle MERGE 是什么?如何实现 UPSERT?

高频 中等 第 16 / 32 题 更新于 2026/07/28
OracleMERGEUPSERT数据同步SQL

简化版

Oracle MERGE 用来把源数据合并到目标表,根据匹配条件决定更新已有记录还是插入新记录,也就是常说的 UPSERT。它常用于数据同步、批量导入、维表更新、ETL。使用时要保证匹配条件唯一可靠,否则可能出现重复匹配或更新结果不确定。

详细版

典型写法:

MERGE INTO target t
USING source s
ON (t.id = s.id)
WHEN MATCHED THEN
  UPDATE SET t.name = s.name
WHEN NOT MATCHED THEN
  INSERT (id, name) VALUES (s.id, s.name);

核心点:

  • MERGE INTO 指定目标表;
  • USING 指定源数据;
  • ON 指定匹配条件;
  • 匹配到执行 UPDATE
  • 没匹配到执行 INSERT
  • 可以增加条件控制是否更新或插入。

MERGE 适合批量同步,不等于所有场景都比单独 INSERTUPDATE 更好。高并发冲突、复杂触发器、唯一约束异常都要考虑。

完整版教学

一、MERGE 解决什么问题

很多业务同步数据时都要判断:

  • 如果目标表已有这条记录,就更新;
  • 如果目标表没有这条记录,就插入。

如果应用层先查再决定插入或更新,代码复杂,而且并发下可能有竞争。MERGE 把这个逻辑放进一条 SQL 中表达。

二、MERGE 的基本结构

示例:

MERGE INTO users t
USING (
  SELECT 1 AS id, 'Tom' AS name FROM dual
) s
ON (t.id = s.id)
WHEN MATCHED THEN
  UPDATE SET t.name = s.name
WHEN NOT MATCHED THEN
  INSERT (id, name) VALUES (s.id, s.name);

这里:

  • users t 是目标表;
  • 子查询 s 是源数据;
  • t.id = s.id 是匹配规则;
  • 匹配到同一用户就更新名字;
  • 没匹配到就插入新用户。

三、MERGE 常用于批量同步

MERGE 的典型场景:

  • 外部系统用户信息同步;
  • 数据仓库维表更新;
  • 临时表导入正式表;
  • 汇总表增量刷新;
  • 配置表批量更新。

比如先把外部数据导入 staging 表,再用 MERGE 合并到正式表,比应用逐行处理更适合数据库批量执行。

四、匹配条件必须可靠

ON 条件是 MERGE 的灵魂。如果匹配条件不唯一,源表一行可能匹配目标多行,或目标一行被源表多行匹配,容易导致错误或结果不符合预期。

推荐做法:

  • ON 使用主键或唯一业务键;
  • 源数据先去重;
  • 目标表建立唯一约束;
  • 合并前检查异常数据;
  • 对复杂更新增加条件。

不要用模糊条件或非唯一字段随便合并。

五、MERGE 和并发冲突

MERGE 不是绕过约束和锁的魔法。目标表有唯一约束时,并发 MERGE 仍可能遇到唯一冲突或锁等待。

例如两个事务同时认为某条数据不存在并尝试插入,最终仍需要唯一约束兜底。应用层要处理异常或设计合适的串行化策略。

所以可靠 UPSERT 的基础仍然是唯一约束,MERGE 是表达合并逻辑的 SQL 手段。

六、常见误区与追问

设计点要求风险
ON 条件主键或唯一业务键非唯一会重复匹配
源数据先去重、清洗一行目标被多行源数据更新
目标表约束唯一约束兜底并发下仍可能冲突

易错点:MERGE 是“表达合并逻辑”的 SQL,不是绕过并发和约束的工具。可靠 UPSERT 仍然要靠唯一键、事务和异常处理兜底。

例如 staging 表里同一个 id=1001 出现 2 行,目标表也按 id 合并。若不先去重,MERGE 可能让同一目标行被多条源记录影响,结果不可控或直接报错。批量同步 10 万行时,先在源表按业务键去重、校验唯一性,通常比等 MERGE 报错后再排查更稳。

  • 误区:MERGE 一定比 INSERT/UPDATE 更快。 MERGE 适合批量合并,但简单单行写入未必比明确的 INSERT 或 UPDATE 更合适。
  • 误区:MERGE 不需要唯一约束。 匹配条件应由主键或唯一业务键支撑,否则并发和重复数据都会放大风险。
  • 误区:MERGE 可以随意更新所有字段。 状态、金额、审计字段要谨慎,避免把目标表里的正确历史值覆盖掉。
  • 追问:USING 可以是什么? 可以是表、视图、子查询或临时 staging 数据,关键是源数据要稳定、去重、可追溯。
  • 追问:并发 MERGE 可能遇到什么问题? 唯一冲突、锁等待、死锁和重复更新都可能出现,应用要能处理异常或重试。
  • 追问:MERGE 适合哪些场景? 外部数据同步、ETL、维表更新、临时表导入正式表、汇总表增量刷新。

七、加强记忆

Oracle MERGE 记住“按条件合并”:匹配就更新,不匹配就插入。它特别适合批量同步和 ETL,但前提是匹配键唯一可靠;并发一致性仍要靠约束、事务和异常处理兜底。