简介


Merge关键字是一个神奇的DML关键字。它在SQL Server 2008被引入,它能将Insert,Update,Delete简单的并为一句。MSDN对于Merge的解释非常的短小精悍:”根据与源表联接的结果,对目标表执行插入、更新或删除操作。例如,根据在另一个表中找到的差异在一个表中插入、更新或删除行,可以对两个表进行同步。”,通过这个描述,我们可以看出Merge是关于对于两个表之间的数据进行操作的。
    可以想象出,需要使用Merge的场景比如:

  • 数据同步
  • 数据转换
  • 基于源表对目标表做Insert,Update,Delete操作

使用Merge关键字的好处


首先是更加短小精悍的语句,在SQL Server 2008之前没有Merge的时代,基于源表对目标表进行操作需要分别写好几条Insert,Update,Delete。而使用Merge,仅仅需要使用一条语句就好。下面我们来看一个例子。
    首先建立源表和目标表,并插入相关的数据,如图1所示。

图1.创建测试表并插入测试数据

下面把图1的脚本用文本贴出来。

--创建源表
CREATE TABLE [dbo].[SourceTable](
[id] int,
[DESC] nvarchar(50)
) --创建目标表
CREATE TABLE [dbo].[TargetTable](
[id] int,
[DESC] nvarchar(50)
) --为源表插入数据
INSERT INTO [dbo].[SourceTable] VALUES(1,'描述1')
INSERT INTO [dbo].[SourceTable] VALUES(2,'描述2')
INSERT INTO [dbo].[SourceTable] VALUES(3,'描述3')
INSERT INTO [dbo].[SourceTable] VALUES(4,'描述4') --为目标表插入数据
INSERT INTO [dbo].[TargetTable] VALUES(1,'在源表里存在,将会被更新')
INSERT INTO [dbo].[TargetTable] VALUES(2,'在源表里存在,将会被更新')
INSERT INTO [dbo].[TargetTable] VALUES(5,'在源表里不存在,将会被删除')
INSERT INTO [dbo].[TargetTable] VALUES(6,'在源表里不存在,将会被删除')

下面我们来写一个简单的Merge语句,如图2所示。

图2.一个简单的Merge语句,注意上面USING关键字后面的SourceTable也可以是一个子查询,例如:

MERGE INTO TargetTable AS T
USING (SELECT id, [DESC] FROM SourceTable) AS S
ON T.id=S.id
WHEN MATCHED
THEN UPDATE SET T.[DESC]=S.[DESC]
WHEN NOT MATCHED
THEN INSERT VALUES(S.id, S.[DESC])
WHEN NOT MATCHED BY SOURCE
THEN DELETE;

所造成的结果如图3所示。

图3.Merge语句对于目标表的更新
 
     最终目标表的结果如图4所示。

图4.最后目标表的结果

 我们还可以在用Merge语句插入(INSERT)数据到TargetTable时,只插入部分列,这在TargetTable中有自增列或默认值列时非常有用,如下所示:

MERGE INTO TargetTable AS T
USING SourceTable AS S
ON T.id=S.id
WHEN MATCHED
THEN UPDATE SET T.[DESC]=S.[DESC]
WHEN NOT MATCHED
THEN INSERT([DESC]) VALUES(S.[DESC]) --只插入DESC列到TargetTable,不插入id列
WHEN NOT MATCHED BY SOURCE
THEN DELETE;

 目标表的结果如图5所示。

 图5.目标表中只插入了列DESC

Merge语句还有一个强大的功能是通过OUTPUT子句,可以将刚刚做过变动的数据进行输出。我们在上面的Merge语句后加入OUTPUT子句,如图6所示。

图6.Merge语句后加上OUTPUT子句
 
   此时Merge操作完成后,将所变动的语句进行输出,如图7所示。

图7.输出Merge操作产生的数据变更

 我们还可以将Merge语句OUTPUT关键字的输出结果存放在另一张表里,供后续使用,如下所示。

CREATE TABLE #MergeResult --定义一个临时表#MergeResult来存放下面MERGE语句OUTPUT关键字的输出结果
(
[结果表_id] INT IDENTITY(1,1),
[结果表_Action] NVARCHAR(50),
[结果表_插入的id] NVARCHAR(50),
[结果表_插入的DESC] NVARCHAR(50),
[结果表_删除的id] NVARCHAR(50),
[结果表_删除的DESC] NVARCHAR(50)
); MERGE INTO TargetTable AS T
USING SourceTable AS S
ON T.id=S.id
WHEN MATCHED --当上面on后面的T.id=S.id时,目标表中的id为1,2的数据被更新
THEN UPDATE SET T.[DESC]=S.[DESC]
WHEN NOT MATCHED --目标表中没有的id,在源表中有,则插入相关数据
THEN INSERT VALUES(S.id, S.[DESC])
WHEN NOT MATCHED BY SOURCE --目标表中存在,源表中不存在,则删除
THEN DELETE
OUTPUT
$ACTION AS [ACTION],
Inserted.id AS 插入的id,
Inserted.[DESC] AS 插入的DESC,
Deleted.id AS 删除的id,
Deleted.[DESC] AS 删除的DESC
INTO #MergeResult([结果表_Action],[结果表_插入的id],[结果表_插入的DESC],[结果表_删除的id],[结果表_删除的DESC]); --将OUTPUT关键字后的输出结果插入表#MergeResult SELECT * FROM #MergeResult; --查询表#MergeResult

 最后临时表#MergeResult的结果如图8所示。

 图8.临时表#MergeResult的结果

当然了,上面的Merge关键字后面使用了多个WHEN…THEN语句,而这个语句是可选的.也可以仅仅新增或是仅仅删除,如图9所示。

图9.仅仅插入的Merge语句

我们还可以使用TOP关键字限制目标表被操作的行,如图10所示。在图2的语句基础上加上了TOP关键字,我们看到只有两行被更新。

图10.使用TOP关键字的Merge语句
 
    但仅仅是MATCHED这种限制条件往往不能满足实际需求,我们可以在图9那个语句的基础上加上AND附加上额外的限制条件,如图11所示。

图11.加上了AND限制条件的Merge语句

Merge关键字的一些限制


  • 使用Merge关键字只能更新一个表
  • 源表中不能有重复的记录

小结


本文简单说明了Merge关键字的使用。如果你使用的是SQL Server 2008之后的版本,在面对一些比如库存结账之类的业务时,放弃IF…ELSE和手写UPDATE,Insert吧,使用Merge关键字可以使这类操作更加轻松愉悦。

原文链接

SQL Server中的Merge关键字(转载)的更多相关文章

  1. 【转载】SQL Server中的Merge关键字

    简介 原文地址 Merge关键字是一个神奇的DML关键字.它在SQL Server 2008被引入,它能将Insert,Update,Delete简单的并为一句.MSDN对于Merge的解释非常的短小 ...

  2. SQL Server 中的Merge关键字(转载)

    简介 Merge关键字是一个神奇的DML关键字.它在SQL Server 2008被引入,它能将Insert,Update,Delete简单的并为一句.MSDN对于Merge的解释非常的短小精悍:”根 ...

  3. SQL Server中的Merge关键字

    本文转载地址:http://www.cnblogs.com/CareySon/archive/2012/03/07/2383690.html 简介 Merge关键字是一个神奇的DML关键字.它在SQL ...

  4. SQL Server中的Merge关键字 更新表数据

    简介 Merge关键字是一个神奇的DML关键字.它在SQL Server 2008被引入,它能将Insert,Update,Delete简单的并为一句.MSDN对于Merge的解释非常的短小精悍:”根 ...

  5. sql server中的merge

    http://www.cnblogs.com/CareySon/archive/2012/03/07/2383690.html 简介 Merge关键字是一个神奇的DML关键字.它在SQL Server ...

  6. c#Winform程序调用app.config文件配置数据库连接字符串 SQL Server文章目录 浅谈SQL Server中统计对于查询的影响 有关索引的DMV SQL Server中的执行引擎入门 【译】表变量和临时表的比较 对于表列数据类型选择的一点思考 SQL Server复制入门(一)----复制简介 操作系统中的进程与线程

    c#Winform程序调用app.config文件配置数据库连接字符串 你新建winform项目的时候,会有一个app.config的配置文件,写在里面的<connectionStrings n ...

  7. 转载: SQL Server中的索引

    http://www.blogjava.net/wangdetian168/archive/2011/03/07/347192.html 1 SQL Server中的索引 索引是与表或视图关联的磁盘上 ...

  8. [转载]SQL Server查找包含某关键字的存储过程3种方法

    存储过程都写在一个指定的表中了,我们只要使用like查询就可以实现查询当前这台SQL Server中所有存储过程中包括了指定关键字的存储过程并显示出来,下面一起来看看我总结了几条命令. 例子1 代码如 ...

  9. 浅谈SQL Server中的三种物理连接操作(HASH JOIN MERGE JOIN NESTED LOOP)

    简介 在SQL Server中,我们所常见的表与表之间的Inner Join,Outer Join都会被执行引擎根据所选的列,数据上是否有索引,所选数据的选择性转化为Loop Join,Merge J ...

随机推荐

  1. 【代码笔记】Web-Javascript-JavaScript简介

    一,效果图. 二,代码. <!DOCTYPE html> <html> <head> <meta charset="utf-8"> ...

  2. 【代码笔记】Web-利用Dreamweaver实现form

    一,打开Dreamweaver---->File---New---->如下图所示.选择HTML,点击OK. 二,会出现如下图所示界面.把光标放到Body处. 三,将上面的栏切换到Desig ...

  3. 遇到了ImportError: libmysqlclient_r.so.16: cannot open shared object file: No such file or directory

    解决方法如下: 1. 通过命令查找libmysqlclient_r.so.16 在什么地方,一般是在/usr/lib64/mysql/下面 2. 做一个链接到/usr/lib64 下: ln -s / ...

  4. 微软Azure AspNetCore微服务实战 第一期

    微服务大家已经不在陌生了,相对传统单体架构其带来了更大的灵活性与多方位的效率提升. 2017官方发布了EshopOnContainers的微服务项目,其结合了.Net Core.Azure.Docke ...

  5. PyCharm实现高效远程调试代码

      PyCharm实现高效远程调试代码   (薛刚强)    为方便Python代码学习和项目开发,目前选择专业的 IDE 开发工具 ,如 PyCham.针对个人使用的技巧做个笔记,分享给大家,有描述 ...

  6. Linux 下修改网卡MAC地址

    Linux下修改网卡MAC地址 by:授客 QQ:1033553122 例子:修改网卡接口eth0的mac地址 #停用网卡接口,比如eth0 # ifconfig eth0 down #编辑对应的网卡 ...

  7. call/apply以及this指向的理解

    javascript是面向对象的语言,Function也是一种对象,有自己的属性和方法.call和apply就是js函数自带方法,挂在Fucntion.prototype上. 一般调用某函数时,直接“ ...

  8. 将mssql数据库高版本迁移到低版本

    将mssql数据库高版本迁移到低版本 在低版本目标数据库中创建目标空数据库[TargetDb] ,注意新建数据库即可,不要创建任何表 在低版本数据库中,选中[服务器对象=>链接服务器] 右键[新 ...

  9. 如何检查oracle的归档日志及空间占用率,清除归档日志

    如何解决“归档日志已满问题” 问题描述: 所用数据库为 Oracle 10g ,模式为归档模式,oracle 系统默认的归档空间为2G,由于日志过多,空间写满,数据库的redo文件不能归档,而出现or ...

  10. 3.7Python数据处理篇之Numpy系列(七)---Numpy的统计函数

    目录 目录 前言 (一)函数一览表 (二)统计函数1 (三)统计函数2 目录 前言 具体我们来学Numpy的统计函数 (一)函数一览表 调用方式:np.* .sum(a) 对数组a求和 .mean(a ...