您好,欢迎访问一九零五行业门户网

使用MERGE语句同步表

先建好测试环境: use tempdbgoif object_id(t1) is not null drop table t1if object_id(t2) is not null drop table t2gocreate table t1(id1 int,val1 varchar(50))create table t2(id2 int,val2 varchar(50))goinsert into t1select 1,a union allselect
先建好测试环境: use tempdbgoif object_id('t1') is not null drop table t1if object_id('t2') is not null drop table t2gocreate table t1(id1 int,val1 varchar(50))create table t2(id2 int,val2 varchar(50))goinsert into t1select 1,'a' union allselect 2,'b' union allselect 3,'c'现在我们的目标是让t2表与t1表同步,我直接把完整的merge语句帖上来,等下再细说各个部分:
merge into t2 as tb_targetusing t1 as tb_sourceon tb_target.id2=tb_source.id1when not matched by target then insert(id2,val2)values(id1,val1)when not matched by source thendeletewhen matched and tb_target.val2tb_source.val1 then update settb_target.val2=tb_source.val1output $action,isnull(deleted.id2,inserted.id2) as id,deleted.val2,inserted.val2;看看merge语句输出的结果/*$action id2 val2 val2---------- ----------- -------------------------------------------------- --------------------------------------------------insert 1 null ainsert 2 null binsert 3 null c*/再看一下现在t2的内容:select * from t2/*id2 val2----------- --------------------------------------------------1 a2 b3 c*/可以看到t1的东东已经过去了,也就是说初步的同步完成了。现在做一些其它的操作,我们分别插入、更新、删除一条数据:update t1 set val1='d' where id1=3delete from t1 where id1=2insert into t1select 4,'e'select * from t1 /*id1 val1----------- --------------------------------------------------1 a4 e3 d*/现在各种数据都有了,1没变,2删了,3改了,4是加的。再运行上面那坨merge语句:merge into t2 as tb_targetusing t1 as tb_sourceon tb_target.id2=tb_source.id1when not matched by target then insert(id2,val2)values(id1,val1)when not matched by source thendeletewhen matched and tb_target.val2tb_source.val1 then update settb_target.val2=tb_source.val1output $action,isnull(deleted.id2,inserted.id2) as id,deleted.val2,inserted.val2;/*$action id val2 val2---------- ----------- -------------------------------------------------- --------------------------------------------------insert 4 null edelete 2 b nullupdate 3 c d*/看一下t2的数据select * from t2/*id2 val2----------- --------------------------------------------------1 a3 d4 e*/可以看到,数据已经完全同步了。看到效果后,我们就可以开始说正文了,我再粘一次merge语句,然后一句一句细说merge into t2 as tb_targetusing t1 as tb_sourceon tb_target.id2=tb_source.id1when not matched by target then insert(id2,val2)values(id1,val1)when not matched by source thendeletewhen matched and tb_target.val2tb_source.val1 then update settb_target.val2=tb_source.val1output $action,isnull(deleted.id2,inserted.id2) as id,deleted.val2,inserted.val2;1.merge into t2 as tb_target指定要同步的目标表。merge是关键字,into可有可无,t2是目标表名,as可有可无,tb_target是表别名。如果要对目标表加表提示和索引提示,比如with(...),加在t2和as中间就可以了。2.using t1 as tb_source指定用来作为同步源的表或其它东东。using是关键字,t1是原表名或一个子查询,比如一堆join出来的东西用括号括起来。as同上,tb_source是别名。3.on tb_target.id2=tb_source.id1关联条件,没什么好说的,注意这里开始就用到上面定义的别名了。4.when not matched by target theninsert(id2,val2)values(id1,val1)这里放到一起说。看到insert应该就能猜这段语句的意思是“如果原表有的记录新表没有,就插入”。not matched表示不匹配, by target表示是新表找不到匹配原表条件(就是上面的on后写的)的记录, by target 可以不写,默认就是by target,但如果要写两个when matched就必须要写,比如上面这个merge。第二三行和普通的插入语句差不多,区别就在于没有目标表名和只能用values不能用select,因为这里都是针对单行的操作。5.when not matched by source thendelete这个就简单了,如果是原表找不到新表的匹配记录,就把新表的删了。需要注意的就是如果要加上这句,上面的not matched必须加by target。6.when matched and tb_target.val2tb_source.val1 then update settb_target.val2=tb_source.val1第一行后面的and部分可以不要,相当于更新的另一个匹配条件,像上面例子中,id为1的那条数据没有动,但因为能找到匹配记录还是会更新,加上条件就可以避免这种无效操作了。7.output $action,isnull(deleted.id2,inserted.id2) as id,deleted.val2,inserted.val2这行可以都去掉,作用就是输出同步的数据,用过触发器的同学对inserted和deleted两个表应该灰常熟悉,分别放的是更新后的值和更新前的值,看看最后一次merge输出的信息就能差不多看出门道了,我就不多说了。如果要调试语句的话,可以加上这句,正常的同步就可以去掉了。8.;这个必须有。。。。。总之,4,5,6,7都是可以去掉的,但4,5,6至少要有一个,这就是merge的全部常用语法了。还有一个最后可以加 option查询提示 最后简单对比一下merge和原本同样效果的操作的io对比merge into t2 as tb_targetusing t1 as tb_sourceon tb_target.id2=tb_source.id1when not matched by target then insert(id2,val2)values(id1,val1)when not matched by source thendeletewhen matched and tb_target.val2tb_source.val1 then update settb_target.val2=tb_source.val1output $action,isnull(deleted.id2,inserted.id2) as id,deleted.val2,inserted.val2; /*表 't2'。扫描计数 2,逻辑读取 7 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。表 't1'。扫描计数 2,逻辑读取 4 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。*/ print '------------------------------------------------------------------------------------'insert into t2(id2,val2)select id1,val1from t1 where not exists(select 1 from t2 where t2.id2=t1.id1)update t2set t2.val2=t1.val1from t2inner join t1 on t2.id2=t1.id1and t2.val2t1.val1delete from t2 where not exists(select 1 from t1 where t1.id1=t2.id2) /*表 't2'。扫描计数 1,逻辑读取 4 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。表 'worktable'。扫描计数 1,逻辑读取 5 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。表 't1'。扫描计数 1,逻辑读取 1 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。表 't2'。扫描计数 1,逻辑读取 2 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。表 't1'。扫描计数 1,逻辑读取 4 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。表 't2'。扫描计数 1,逻辑读取 1 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。表 't1'。扫描计数 1,逻辑读取 4 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。*/
其它类似信息

推荐信息