SQL Server 2008中SQL增强之三:Merge(在一条语句中使用Insert,Update,Delete)

SQL Server 2008提供了一个增强的SQL命令Merge,用法参看MSDN:http://msdn.microsoft.com/zh-cn/library/bb510625.aspx

功能:根据与源表联接的结果,对目标表执行插入、更新或删除操作。例如,根据在另一个表中找到的差异在一个表中插入、更新或删除行,可以对两个表进行同步。

我们看一个例子,假如,有一总产品列表,一个分店产品列表,需要从分店添加产品时更新总产品列表。

总产品表,分店产品表结构完全一致:

if OBJECT_ID('Demo_AllProducts') is not null drop table Demo_AllProducts go Create table Demo_AllProducts (PKID int not null identity(1,1) primary key ,DName Nvarchar(20) null ,DCode NVarchar(30) null ,DDate datetime null ) go
--this SQL is only for SQL Server 2008 Insert into Demo_AllProducts (DName,DCode,DDate) values ('DemoA','AAA',GETDATE()), ('DemoB','BBB',GETDATE()), ('DemoC','CCC',GETDATE()), ('DemoD','DDD',GETDATE()), ('DemoE','EEE',GETDATE())
select * from Demo_AllProducts
--PKID    DName    DCode    DDate --1    DemoA    AAA    2010-10-12 20:33:54.417 --2    DemoB    BBB    2010-10-12 20:33:54.417 --3    DemoC    CCC    2010-10-12 20:33:54.417 --4    DemoD    DDD    2010-10-12 20:33:54.417 --5    DemoE    EEE    2010-10-12 20:33:54.417

if OBJECT_ID('Demo_Shop1_Product') is not null drop table Demo_Shop1_Product go
Createtable Demo_Shop1_Product (PKID int not null identity(1,1) primary key ,DName Nvarchar(20) null ,DCode NVarchar(30) null ,DDate datetime null ) go
--this SQL is only for SQL Server 2008 Insert into Demo_Shop1_Product (DName,DCode,DDate) values ('DemoA','AAA',GETDATE()), ('DemoB','CCC',GETDATE()), ('DemoF','FFF',GETDATE())
select * from Demo_Shop1_Product
--PKID    DName    DCode    DDate --1    DemoA    AAA    2010-10-17 20:19:32.767 --2    DemoB    CCC    2010-10-17 20:19:32.767 --3    DemoF    FFF    2010-10-17 20:19:32.767

假定现在需要将分店数据完全合并到总产品表中,以编码字段为依据,如果产品名称不致,则用分店的产品名称替换总产品名称。

如果总产品表中不存在,则添加。

可选项:如果分店表中不存在,则从总产品表中删除分店中没有的行。如果这样,总产品表和分店表就完全同步了。实际操作中可能不需要删除目标表的行。

语句如下:

--确定目标表 Merge Into Demo_AllProducts p --从数据源查找编码相同的产品 using Demo_Shop1_Product s on  p.DCode=s.DCode --如果编码相同,则更新目标表的名称 When Matched and P.DName<>s.DName Then Update set P.DName=s.DName --如果目标表中不存在,则从数据源插入目标表 When Not Matched By Target Then Insert (DName,DCode,DDate) values (s.DName,s.DCode,s.DDate) --如果数据源的行在源表中不存在,则删除源表行 When Not Matched By Source Then Delete;

此时,执行完成后,两个表的行均如下:

--PKID    DName    DCode    DDate --1    DemoA    AAA    2010-10-17 20:31:00.827 --2    DemoB    CCC    2010-10-17 20:31:00.827 --3    DemoF    FFF    2010-10-17 20:31:00.827

如果不删除,语句如下:

--确定目标表 Merge Into Demo_AllProducts p --从数据源查找编码相同的产品 using Demo_Shop1_Product s on  p.DCode=s.DCode --如果编码相同,则更新目标表的名称 When Matched and P.DName<>s.DName Then Updateset P.DName=s.DName --如果目标表中不存在,则从数据源插入目标表 When Not Matched By Target Then Insert (DName,DCode,DDate) values (s.DName,s.DCode,s.DDate);

执行后结果:

--PKID    DName    DCode    DDate --1    DemoA    AAA    2010-10-17 20:30:28.350 --2    DemoB    BBB    2010-10-17 20:30:28.350 --3    DemoB    CCC    2010-10-17 20:30:28.350 --4    DemoD    DDD    2010-10-17 20:30:28.350 --5    DemoE    EEE    2010-10-17 20:30:28.350 --6    DemoF    FFF    2010-10-17 20:31:00.827 --PKID    DName    DCode    DDate --1    DemoA    AAA    2010-10-17 20:31:00.827 --2    DemoB    CCC    2010-10-17 20:31:00.827 --3    DemoF    FFF    2010-10-17 20:31:00.827

如果需要记录Merge语句影响的行,可以用Output子句,如果仅仅需要知道影响的行数,可以使用@@ROWCOUNTROWCOUNT_BIG(),修改后的示例如下:

--定义表变量以存储输出 Declare@tableVarRecordTable (MPKID int not null identity(1,1) primary key ,PKID int null ,DName Nvarchar(20) null ,DCode NVarchar(30) null ,DDate datetime null )
--确定目标表 Merge Into Demo_AllProducts p --从数据源查找编码相同的产品 using Demo_Shop1_Product s on  p.DCode=s.DCode --如果编码相同,则更新目标表的名称 When Matched and P.DName<>s.DName Then Updateset P.DName=s.DName
--如果目标表中不存在,则从数据源插入目标表 When Not Matched By Target Then Insert (DName,DCode,DDate) values (s.DName,s.DCode,s.DDate)
--如果数据源的行在源表中不存在,则删除目标表行 When Not Matched By Source Then Delete  OUTPUT deleted.* INTO @tableVarRecord; ----Delete  OUTPUT Inserted.* INTO @tableVarRecord; --返回上个Merge语句影响的行数 select @@ROWCOUNT as Count1,ROWCOUNT_BIG() as Count2
select * from @tableVarRecord;

结果:

--影响的行数 --Count1    Count2 --5    5 --Deleted表的行 --MPKID    PKID    DName    DCode    DDate --1    NULL    NULL    NULL    NULL --2    2    DemoB    BBB    2010-10-17 21:42:30.700 --3    3    DemoC    CCC    2010-10-17 21:42:30.700 --4    4    DemoD    DDD    2010-10-17 21:42:30.700 --5    5    DemoE    EEE    2010-10-17 21:42:30.700

关于@@ROWCOUNTROWCOUNT_BIG()的更多说明,请查阅MSDN:

http://technet.microsoft.com/zh-tw/library/ms187316.aspx 

http://msdn.microsoft.com/en-us/library/ms181406.aspx

如果影响的结果超过20亿,即整型的最大范围,请使用后者。

posted on 2015-01-13 17:02 lsyyx 阅读(...) 评论(...) 编辑 收藏

转载于:https://www.cnblogs.com/lsyyx/p/4221809.html

SQL Server 2008中SQL增强之三:Merge(在一条语句中使用Insert,Update,Delete)相关推荐

  1. 结局就在附近! (对于SQL Server 2008和SQL Server 2008 R2)

    介绍 (Introduction) As with everything else, all good things must come to an end. After hanging around ...

  2. SQL Sever 各版本下载 SQL Server 2012下载SQL Server 2008下载SQL Server 2005 下载SQL Server 2000 下载...

    SQL Server 2016简体中文企业版 文件名:cn_sql_server_2016_enterprise 64位下载地址:ed2k://|file|cn_sql_server_2016_ent ...

  3. SQL Sever 各版本下载 SQL Server 2012下载SQL Server 2008下载SQL Server 2005 下

    SQL Sever 各版本下载 SQL Server 2012下载SQL Server 2008下载SQL Server 2005 下载SQL Server 2000 下载 SQL Server 20 ...

  4. sql服务器状态已停止,SQL SERVER 2008 SSMS - SQL Server Management Studio 已停止工作

    Overall summary: Final result:                  已通过 Exit code (Decimal):           0 Exit message:   ...

  5. 用友nc633与oracle,用友NC63安装到SQL server 2008 R2和oracle上的表空间创建语句

    NC安装到oracle的表空间创建SQL语句: alter system set "_optimizer_cartesian_enabled"=false; alter syste ...

  6. C语言中||和能同时出现在一条语句中吗?

    &&和||在同一条语句中会有问题吗? 1.正文 1.1.问题 2.&&和||优先级与其他运算符优先级 3.0&&1和0||1等于啥? 4.详解 4.1. ...

  7. SQL SERVER 2008查看sql执行的时间

    set statistics profile on set statistics io on set statistics time on go <这里写上你的语句...> go set ...

  8. mysql外键设置sql语句,SQL Server 2008之SQL语句外键

    xin3721网络学院为广大学员,准备了丰富了教学视频.为了更好的让大学配合视频进行学习,拓展学员的知 识面,我站特整理了大量的,技术文章,供学员参考.因此本教案需配合视频教程学习, 视频教程地址为: ...

  9. SQL SERVER 2008的top增强

    create table testTop (  value int primary key ) --可以一次插入顶部的多条记录 insert top(5) into testTop  select * ...

最新文章

  1. python对视频画框标记后保存
  2. pytorch MaxUnpool2d
  3. 电容屏物体识别_兆易创新的传感器布局:电容/光学/超声指纹/ToF全面发力
  4. Taro+react开发(11)--不能加分号
  5. 第八届“图灵杯”NEUQ-ACM程序设计竞赛个人赛(同步赛)解题报告
  6. ioc spring 上机案例_抛开Spring去理解IOC思想 - 原来IOC容器这么简单
  7. Bootstrap进度条的颜色
  8. Android异步批量下载图片并缓存
  9. 8.1 Zend_View(2)
  10. java实现选择排序+图解+代码解析
  11. LINUX占用太多内存的解决方法
  12. Web测试中性能测试基础
  13. 使用python将豆瓣妹子的图片批量搬运到百度网盘
  14. 《PMP学习笔记》1.3 五大过程组十大知识领域
  15. 如何使用Bootbox ?
  16. 互联网日报 | 张朝阳宣布2020年搜狐已盈利;永辉超市达成千店目标;腾讯云原生注册用户规模超100万...
  17. 基于asp.net714零食销售海米跨境电子商务商城
  18. 【Vue报错】This is probably not a problem with npm. There is likely additional logging output above
  19. 1到100的偶数之和是多少_求1到100之间所有偶数之和
  20. Auditbeat日志审计方案

热门文章

  1. MySQL数据库优化总结
  2. 【laravel】用laravel在游览器中显示Hello World
  3. svn服务安装和配置 以及搭配Eclips插件使用(总结)
  4. DP【洛谷P2134】 百日旅行
  5. (二)行为化参数传递代码
  6. 【原创】sharepoint webpart COPY部署的办法
  7. iOS APP上架被拒重新提交审核教程
  8. 并发编程之 锁的优化有哪些
  9. python 下载小说
  10. CSS实现垂直居中的5种思路