SQL Server里那个挺好用的merger工具,讲讲它怎么帮你合并数据啥的
- 问答
- 2026-01-16 04:42:43
- 3
你说的SQL Server里那个挺好用的合并工具,正式名字叫MERGE语句,很多人喜欢叫它“upsert”,这个叫法其实更形象,因为它把更新(update)和插入(insert)合二为一了,它的核心想法特别直接:你手头有一堆新的数据,比如一个刚导出的Excel表格,或者一个临时表,你想用这批新数据去更新数据库里那个主表,这时候,你希望的是:如果主表里已经有某条记录了(比如根据身份证号或者产品编号来判断),那就用新数据把它更新一下;如果主表里没有这条记录,那就直接把这条新记录插进去。
听起来很简单对吧?但要是没有MERGE这个工具,你得写一大堆啰嗦的代码才能搞定,你得先写个查询,看看哪些数据在主表里已经存在,然后针对这批存在的数据写一个UPDATE语句;你再写另一个查询,找出哪些数据在主表里不存在,然后再为这批不存在的数据写一个INSERT语句,整个操作还得包在一个事务里,确保要么全部成功,要么全部失败,不然数据就乱套了,这一通折腾,代码又长又容易出错。
而MERGE语句就像个智能机器人,你只需要告诉它三件事,它就能帮你把活儿干得漂漂亮亮:

- 目标是谁:你要更新哪个主表(Target)。
- 来源是谁:你手里的新数据来自哪里(Source),可以是一个表,也可以是一个子查询结果。
- 怎么认人:根据哪个或哪几个字段来判断目标表和来源表里的记录是“同一个人”(匹配条件),这个条件就像是连接两个表的桥梁,通常用主键或唯一键,比如
ON 目标表.员工ID = 来源表.员工ID。
定好了这三点,接下来你就可以给这个机器人下达详细的指令了,也就是告诉它在不同情况下该怎么做,主要是三种情况:
- 当匹配上了(记录在两个表里都存在):这时候你通常是想用来源表的新数据去更新目标表的旧数据,你就写一个
WHEN MATCHED THEN子句,后面跟上具体的UPDATE操作。UPDATE SET 目标表.工资 = 来源表.新工资,目标表.部门 = 来源表.新部门。 - 当没匹配上(记录在来源表里有,但目标表里没有):这说明这是一条全新的记录,需要插入到目标表里,你就写一个
WHEN NOT MATCHED BY TARGET THEN子句,后面跟上INSERT操作,把来源表里这条记录的值插到目标表里。 - 当没匹配上(记录在目标表里有,但来源表里没有):这种情况稍微少见一点,但有时候也需要处理,你的来源表是一份当前在职员工名单,那么目标表里那些在来源表里找不到的员工,可能就是已经离职了,这时候你可以写一个
WHEN NOT MATCHED BY SOURCE THEN子句,后面可以跟一个DELETE操作,把目标表里这条记录删掉(标记为离职),或者跟一个UPDATE操作,把它的状态改为“无效”。
你可以把这三种情况都写上,也可以只写你需要的一两种,用一个分号结束整个MERGE语句,它就会自动按照你的指令去执行了。

举个例子吧,假设你是一个超市的库管,你每天会收到一份从总部系统导出的最新库存清单(当作来源表),你需要用它来更新你本地数据库里的库存表(目标表),你用MERGE语句,把匹配条件定为“商品条码相等”。
- 对于两个表里都有的商品(匹配上了),你就用来源表里的最新库存数量更新目标表。
- 对于来源表里有而目标表里没有的商品(没匹配上),说明是新采购的商品,你就把它插入到目标表里。
- 对于目标表里有而来源表里没有的商品(反向没匹配上),可能意味着这个商品已经下架不再销售了,你可以选择把它的库存数量清零,或者标记为“停售”。
你看,一个MERGE语句就把插入新商品、更新库存、处理下架商品这几件事全包了,代码清晰又简洁,而且因为它是一个原子操作,数据库会保证所有步骤要么一起成功,要么一起回滚,你不用操心数据不一致的问题。
使用MERGE语句也有个小地方需要注意,就像微软官方文档里提醒的那样(来源:Microsoft Docs - MERGE (Transact-SQL) 的“备注”部分),因为MERGE语句功能比较强大,涉及的操作可能有点复杂,所以在写的时候要特别小心那个匹配条件(ON子句),一定要确保它能准确地关联到正确的行,如果条件写得不严谨,可能会导致更新了不该更新的数据,所以最好在正式对生产环境操作前,先在测试环境里验证一下。
MERGE语句是一个非常实用、高效的工具,它把以前需要分好几步完成的“有则更新、无则插入”的操作,浓缩成一步,大大简化了代码,提高了开发效率,也减少了出错的概率,当你需要同步两个表的数据时,它绝对是首选。
本文由酒紫萱于2026-01-16发表在笙亿网络策划,如有疑问,请联系我们。
本文链接:http://www.haoid.cn/wenda/81586.html
