写在前面的话:之前看过Merge语句,感觉没什么用,完全可以用其他的方式来替代,最近又看了看Merge语句,确实挺好用,可以少写很多代码,看起来也很紧凑,当然也有别的优点。

====正文开始=====

  SQL Server 2008 引入了Merge关键字,主要是在一条语句里面可以执行insert、update、delete操作,以实现用一个源对象的数据对目标对象数据进行操作。注意这里的”源对象“和”目标对象“我用黑色标注了,源对象和目标对象实际上不仅仅可以是表Table,还可以是临时表、视图、表变量、CTE,同时”目标对象“还可以是Select语句,说这么多其实想表达Merge语句可以很灵活的使用,但是我们理解的话,可以把”源对象“和”目标对象“想象成Table就行了,毕竟临时表、视图、表变量、CTE也都可以想象成Table。

(注意:如果目标对象是视图的话,那么对目标对象的操作,如update,实际上是对生成视图的表进行操作的)。

  好了,看完上面的文字,你可能已经看不下去了,之所以写上面的话,是为了显得严谨一些,接下来就用例子来讲解吧,这个例子不涉及业务逻辑,可以专注于理解Merge的用法,至于实际中什么时候用,只能自己悟了,好了,开始举例子。

  例如有一个Student_Target表,如下表一,另外一个Student_Source表,如下表二

  执行如下SQL语句:

MERGE INTO Student_Target AS st   --这里是目标表,它将要被源表Merge
USING Student_Source AS ss       --这里是源表
ON st.Sno = ss.Sno          --这里是匹配条件
    WHEN MATCHED           --When和Then是配套的,当st.sno=ss.sno时,用ss.sname更新st.sname,我们看到这里update后面没有写明更新的表,这里更新的是目标表
        THEN UPDATE SET st.Sname = ss.Sname
    WHEN NOT MATCHED BY TARGET  --目标表中不存在,而源表中存在数据,那么就执行insert操作,这里by target可以省略,但是建议加上
        THEN INSERT VALUES    ( ss.Sno,ss.Sname)
    WHEN NOT MATCHED BY SOURCE   --当目标表中存在,而源表中不存在数据,那么就执行delete操作,这里使用了by source
		THEN DELETE
;

  上面SQL语句的意思可以看后面的注释,这里再做一简要说明:对于表一,sno=1的一行和表二sno=1的匹配,所以表一中该行被更新;表一中sno=2,3在表二中不存在,因此delete,表二中sno=4但是在表一中不存在,因此insert,最后结果如下:

  我们看到上面的结果和表二的内容是一样的,其实你再分析一下上面的SQL语句,逻辑就是把表二的内容弄进表一,表一中和表二中不一致的数据删除,似乎我们上面的Merge语句显得很多余。这里想再说明几点:

(1)我们When matched、When not matched by target、when not matched by source都写上了,其实是可选的,我们可以根据自己的需求只使用其中的部分。

(2)前面是Merge into Student_Target as st,其实可以增加top(n)来对特定数量的行进行操作。执行如下SQL:

MERGE TOP(2) INTO Student_Target AS st   --这里是目标表,它将要被源表Merge
USING Student_Source AS ss       --这里是源表
ON st.Sno = ss.Sno          --这里是匹配条件
    WHEN MATCHED           --When和Then是配套的,当st.sno=ss.sno时,用ss.sname更新st.sname,我们看到这里update后面没有写明更新的表,这里更新的是目标表
        THEN UPDATE SET st.Sname = ss.Sname
    WHEN NOT MATCHED BY TARGET  --目标表中不存在,而源表中存在数据,那么就执行insert操作,这里by target可以省略,但是建议加上
        THEN INSERT VALUES    ( ss.Sno,ss.Sname)
    WHEN NOT MATCHED BY SOURCE   --当目标表中存在,而源表中不存在数据,那么就执行delete操作,这里使用了by source
		THEN DELETE
;

  最后结果如下:

  所以,增加了top(2),那么目标表可以被操作的行只能是2条,上面的update操作一条,insert操作一条,达到2条,因此后面的delete就不影响了。因此,对于top(n)应该能够正确的理解。

(3)前面when matched 其实还可以配合其他条件一起操作,例如when matched 可以修改为when matched and ss.sno=1或者when matched and st.sno=1;对于when not matched,只能够使用源列,也就是说,增加and ss.sno=1可以,但是增加and st.sno=1就会报错了。

(4)Merge最后一定要以分号结尾,表示这个Merge句子完整了。

  前面的操作我们看到默认的都是对Target表的操作,有时候我们想对Target表操作后,还能够针对特定的条件,对Source表进行操作,这是就可以配合Output子句一起,来完成我们想要的操作。这里Output字句不单单是针对merge语句的,对于insert、update、delete等操作也可以用的,所以具体的可以再去单独研究研究output子句。

  至此,本文也该告一段落,如何使用Merge语句应该也没有问题。可是心中仍然有一个结,正如上篇文章所写的:如何理解group by和聚合函数中对group by和聚合函数的认识一样,虽然用起来不成问题,但是总是希望能够找到一个天马行空的想法,能够换个角度去认识。比如为啥基本上都是when matched后面跟update,when not matched by target后面跟insert,when not matched by source 后面跟delete呢?为啥when not matched by target后面不能跟delete?为啥when not matched by source后面不能跟insert呢?当然可能还有其他疑问,目前可以跟join结合起来应该能够很好的解释清楚,可是现在还无法用很好的文字逻辑去表达清楚,回头想好怎么写了再写吧,请原谅我又”胡思乱想“了。

  备注:上面的结已经解开了,可以看下一篇博文:如何理解T-SQL中Merge语句(二)

(完)

文档信息

如何理解T-SQL中Merge语句的更多相关文章

  1. 如何理解T-SQL中Merge语句(二)

    写在前面的话:上一篇写了如何理解T-SQL中Merge语句,基本把Merge语句要讲的给讲了,在文章的后面,抛出了几个结,当时没有想明白怎么去用文字表达,这一篇就来解答一下这几个结,又是一篇“天马行空 ...

  2. SQL中Merge的用法

    SQL中Merge的用法 Merge的用法 Merge可以完成以下功能: 1.  两个表之间数据的更新 2.  进行进销存更新库存 3.  进行表之间数据的复制 语法说明: 1.  在语句结束后一定要 ...

  3. SQL中常见语句

    SQL中常见语句笔记: --替换字段中的回车符和换行符 ) ), '') --删除表命令 DROP TABLE [dbo].[MGoods_Test] --删除表中数据命令 DELETE FROM [ ...

  4. SQL Server Merge语句的使用

    Merge关键字在SQL Server 2008被引入,它能将Insert,Update,Delete简单的并为一句.MSDN对于Merge的解释非常的短小精悍:”根据与源表联接的结果,对目标表执行插 ...

  5. Oracle中MERGE语句的使用

    Oracle在9i引入了merge命令, 通过这个merge你能够在一个SQL语句中对一个表同时执行inserts和updates操作. 当然是update还是insert是依据于你的指定的条件判断的 ...

  6. Oracle 中MERGE语句的用法

    原文章出处(http://blog.csdn.net/lichkui/article/details/4306299) MERGE语句是Oracle9i新增的语法,用来合并UPDATE和INSERT语 ...

  7. SQL 中 SELECT 语句的执行顺序

    好像自已在书写 SQL 语句时由于不清楚各个关键字的执行顺序, 往往组织的 SQL 语句缺少很好的逻辑, 凭感觉 "拼凑" ( 不好意思, 如果您的 SQL 语句也经常 " ...

  8. 【SQL】SQL 中Select语句完整的执行顺序

    SQL Select语句完整的执行顺序: 1.from子句组装来自不同数据源的数据: 2.where子句基于指定的条件对记录行进行筛选: 3.group by子句将数据划分为多个分组: 4.使用聚集函 ...

  9. SQL中查询语句的使用

    常用SQL查询语句 - myLittleGarden - 博客园 http://www.cnblogs.com/sunada2005/p/3411873.html 一.简单查询语句 1. 查看表结构 ...

随机推荐

  1. C#通过第三方组件生成二维码(QR Code)和条形码(Bar Code)

    用C#如何生成二维码,我们可以通过现有的第三方dll直接来实现,下面列出几种不同的生成方法: 1):通过QrCodeNet(Gma.QrCodeNet.Encoding.dll)来实现 1.1):首先 ...

  2. 移动端js知识总结

    1.如果使用jquery绑定touch事件的话,获取touchstart,touchmove的触点坐标用 e.originalEvent.targetTouches[0].pageX, 获取touch ...

  3. 连接Linux下 XAMPP集成环境中部署的禅道的数据库MariaDB

    用mysql数据库工具连接linuxmysql环境,但是会遇到连接失败的问题,如下所示: 这就需要涉及到另外的问题了,需要我们打开mysql的连接授权,具体的操作步骤如下: 1)在xshell里进入m ...

  4. Good Bye 2016 - C

    题目链接:http://codeforces.com/contest/750/problem/C 题意:在CF中,每个人都有个Rank值. 当Rank>=1900时,为DIV1.Rank< ...

  5. XSL学习笔记4 XSLT模式匹配的语法

    模板规则通过使用模式来匹配文档树的节点.模式指定一组条件,用于选择要处理的节点.   模式匹配的语法不光可以在<xsl:template>元素的match属性中使用,还可以在<xsl ...

  6. unity3D项目中如何避免硬代码(C#)

    平时做项目,代码中是不允许出现硬代码的,一般我们是怎么处理的呢? 那么硬代码又是什么呢? 我们俗称的硬代码:eg:   label.text = "欢迎来到梦幻岛";  这样我们俗 ...

  7. 苹果手机微信上form表单提交的问题

    场景:前端页面请求后端php,返回带form表单dom元素,然后将其追在页面上,返回的html字段中包含表单自动提交的代码,想法是将带有表单自动提交的dom元素追加到页面上,然后表单自动提交到另外一个 ...

  8. CI框架之HOOKS使用流程及原理

        Ci框架中Hooks可以理解:在框架的执行流程过程中,允许开发者在固定的某些时间点上(如:调用控制器前,调用控制器后等时间点上),调用其他函数来扩充CI框架执行流程的一种方法.技术上来就是通过 ...

  9. margin:0 auto;不居中

    margin:0 auto:不居中可能有以下两个的原因; 1.没有设置宽度<div style="margin:0 auto;"></div>看看上面的代码 ...

  10. Powershell脚本执行权限

    Powershell脚本需要使用PS1扩展名 在加载脚本前需要确认是都有执行权限,默认是Restricted(受限的), 可以执行Get-ExecutionPolicy查看权限, 一般情况下使用 Re ...