设为首页 收藏本站
查看: 2045|回复: 0

[经验分享] SQl Server 2008之Merge示例

[复制链接]

尚未签到

发表于 2018-10-11 11:07:07 | 显示全部楼层 |阅读模式
  在SQL Server 2008的bookonline中对Merge操作的解释为:
根据与源表联接的结果,对目标表执行插入、更新或删除操作。例如,根据在另一个表中找到的差异在一个表中插入、更新或删除行,可以对两个表进行同步。  此操作用处比较广泛,能很好的简化数据更新的过程。其有三个子句:主键匹配更新操作,目标不存在插入操作,源不存在删除操作。当然三个操作在同一个过程中并非必须全部指定,但至少要指定一个操作。具体的语法比较苦涩。下面以具体的例子进行说明:
  有两张结构一致的表:test1,test2。建表语句如下:
  create table test1
  (id int,name varchar(20))
  go
  create table test2
  (id int,name varchar(20))
  go
  insert into test1(id,name)
  values(1,'boyi55'),(2,'51cto'),(3,'bbs'),(4,'fengjicai'),(5,'alis')
  insert into test2(id,name)
  values(1,'boyi'),(2,'51cto')
  1.将test1同步到test2中,没有的数据进行插入,已有数据进行更新
  merge   test2 t --要更新的目标表
  using test1 s --源表
  on t.id=s.id --更新条件(即主键)
  when matched --如果主键匹配,更新
  then update set t.name=s.name
  when not matched then insert values(id,name);--目标主未知主键,插入。此语句必须以分号结束
  运行以下查询查看更新结果
  select a.id,a.name as name_1,b.name as name_2  from test1 as a,test2 as b
  where a.id=b.id
  id          name_1               name_2
  ----------- -------------------- --------------------
  1           boyi55               boyi55
  2           51cto                51cto
  3           bbs                  bbs
  4           fengjicai            fengjicai
  5           alis                 alis
  2.test1中ID为5的记录删除后,用merge同步更新test2。并显示更新内容。

  delete from test1 where>  go
  merge   test2 t
  using test1 s
  on t.id=s.id
  when matched
  then update set t.name=s.name
  when not matched then insert values(id,name);--此处by target可以省略
  when not matched by source then delete--目标中存在源中没有的记录时删除。此处by source不能省略
  output $action ,inserted.name  as new_name,deleted.name as old_name;--输出更新前后name的变化
  $action    new_name             old_name
  ---------- -------------------- --------------------
  UPDATE     boyi55               boyi55
  UPDATE     51cto                51cto
  UPDATE     bbs                  bbs
  UPDATE     fengjicai            fengjicai
  DELETE     NULL                 alis
  3.我们看到上面存在一个问题就是相同的记录也变更新了。因此可以在matched子句中添加一个条件,当更新的列数值不同时再进行更新。在下面的例子中将新建一个表把更新记录写入到日志表中,并且只更新不同记录。
  create table test3(action varchar(20),new_name varchar(20),old_name varchar(20))
  update test1
  set name='boyi555'

  where>  go
  merge   test2 t
  using test1 s
  on t.id=s.id
  when matched and t.name!=s.name
  then update set t.name=s.name
  when not matched then insert values(id,name)
  when not matched by source then delete
  output $action ,inserted.name,deleted.name into test3(action,new_name,old_name);
  select* from test3
  action               new_name             old_name
  -------------------- -------------------- --------------------
  UPDATE               boyi555              boyi55
  4.我们只将删除操作记录到日志中。
  update test1
  set name='bbs.51cto.com'

  where>  go

  delete from test1 where>  go
  insert into test3
  select action,new_name,old_name from
  (
  merge   test2 t
  using test1 s
  on t.id=s.id
  when matched and t.name!=s.name
  then update set t.name=s.name
  when not matched then insert values(id,name)
  when not matched by source then delete
  output $action ,inserted.name ,deleted.name) as del(action,new_name,old_name)
  where action='delete'
  action               new_name             old_name
  -------------------- -------------------- --------------------
  DELETE               NULL                 bbs
  5.如果数据量比较大,同步操作分两次完成,每次只更新50%的数据。
  update test1
  set name=name+'boyi55'
  go
  merge top (50) percent  test2 t
  using test1 s
  on t.id=s.id
  when matched and t.name!=s.name
  then update set t.name=s.name
  when not matched then insert values(id,name)
  when not matched by source then delete
  output $action ,inserted.name ,deleted.name;
  (3 row(s) affected)
  $action    name                 name
  ---------- -------------------- --------------------
  UPDATE     bbs.51cto.comboyi55  bbs.51cto.com
  UPDATE     51ctoboyi55          51cto
  (2 row(s) affected)


运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.iyunv.com/thread-620313-1-1.html 上篇帖子: SQL Server2016从入门到实战 下篇帖子: PHP 通过PDO 连接SQL Server 方式 (两种)
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表