使用MERGE语句同步表
先建好測试环境: USE TEMPDB
GO
IF OBJECT_ID('T1') IS NOT NULL DROP TABLE T1
IF OBJECT_ID('T2') IS NOT NULL DROP TABLE T2
GO
CREATE TABLE T1(ID1 INT,VAL1 VARCHAR(50))
CREATE TABLE T2(ID2 INT,VAL2 VARCHAR(50))
GO
INSERT INTO T1
SELECT 1,'A' UNION ALL
SELECT 2,'B' UNION ALL
SELECT 3,'C' 如今我们的目标是让T2表与T1表同步,我直接把完整的MERGE语句帖上来,等下再细说各个部分:
MERGE INTO T2 AS TB_TARGET
USING T1 AS TB_SOURCE
ON TB_TARGET.ID2=TB_SOURCE.ID1
WHEN NOT MATCHED BY TARGET THEN
INSERT(ID2,VAL2)
VALUES(ID1,VAL1)
WHEN NOT MATCHED BY SOURCE THEN
DELETE
WHEN MATCHED AND TB_TARGET.VAL2<>TB_SOURCE.VAL1 THEN
UPDATE SET
TB_TARGET.VAL2=TB_SOURCE.VAL1
OUTPUT $ACTION,ISNULL(DELETED.ID2,INSERTED.ID2) AS ID,DELETED.VAL2,INSERTED.VAL2
; 看看MERGE语句输出的结果 /* $ACTION ID2 VAL2 VAL2
---------- ----------- -------------------------------------------------- --------------------------------------------------
INSERT 1 NULL A
INSERT 2 NULL B
INSERT 3 NULL C */ 再看一下如今T2的内容: SELECT * FROM T2 /* ID2 VAL2
----------- --------------------------------------------------
1 A
2 B
3 C */ 能够看到T1的东东已经过去了,也就是说初步的同步完毕了。 如今做一些其他的操作,我们分别插入、更新、删除一条数据: UPDATE T1 SET VAL1='D' WHERE ID1=3 DELETE FROM T1 WHERE ID1=2 INSERT INTO T1
SELECT 4,'E' SELECT * FROM T1
/*
ID1 VAL1
----------- --------------------------------------------------
1 A
4 E
3 D
*/ 如今各种数据都有了,1没变,2删了,3改了,4是加的。再执行上面那坨MERGE语句: MERGE INTO T2 AS TB_TARGET
USING T1 AS TB_SOURCE
ON TB_TARGET.ID2=TB_SOURCE.ID1
WHEN NOT MATCHED BY TARGET THEN
INSERT(ID2,VAL2)
VALUES(ID1,VAL1)
WHEN NOT MATCHED BY SOURCE THEN
DELETE
WHEN MATCHED AND TB_TARGET.VAL2<>TB_SOURCE.VAL1 THEN
UPDATE SET
TB_TARGET.VAL2=TB_SOURCE.VAL1
OUTPUT $ACTION,ISNULL(DELETED.ID2,INSERTED.ID2) AS ID,DELETED.VAL2,INSERTED.VAL2
; /* $ACTION ID VAL2 VAL2
---------- ----------- -------------------------------------------------- --------------------------------------------------
INSERT 4 NULL E
DELETE 2 B NULL
UPDATE 3 C D */ 看一下T2的数据 SELECT * FROM T2 /* ID2 VAL2
----------- --------------------------------------------------
1 A
3 D
4 E */ 能够看到,数据已经全然同步了。看到效果后,我们就能够開始说正文了,我再粘一次MERGE语句,然后一句一句细说 MERGE INTO T2 AS TB_TARGET
USING T1 AS TB_SOURCE
ON TB_TARGET.ID2=TB_SOURCE.ID1
WHEN NOT MATCHED BY TARGET THEN
INSERT(ID2,VAL2)
VALUES(ID1,VAL1)
WHEN NOT MATCHED BY SOURCE THEN
DELETE
WHEN MATCHED AND TB_TARGET.VAL2<>TB_SOURCE.VAL1 THEN
UPDATE SET
TB_TARGET.VAL2=TB_SOURCE.VAL1
OUTPUT $ACTION,ISNULL(DELETED.ID2,INSERTED.ID2) AS ID,DELETED.VAL2,INSERTED.VAL2
; 1. MERGE INTO T2 AS TB_TARGET 指定要同步的目标表。MERGE是keyword,INTO可有可无,T2是目标表名,AS可有可无,TB_TARGET是表别名。 假设要对目标表加表提示和索引提示,比方WITH(...),加在T2和AS中间就能够了。 2. USING T1 AS TB_SOURCE 指定用来作为同步源的表或其他东东。USING是keyword,T1是原表名或一个子查询,比方一堆JOIN出来的东西用括号括起来。 AS同上,TB_SOURCE是别名。 3. ON TB_TARGET.ID2=TB_SOURCE.ID1 关联条件,没什么好说的,注意这里開始就用到上面定义的别名了。 4. WHEN NOT MATCHED BY TARGET THEN INSERT(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 THEN
DELETE 这个就简单了,假设是原表找不到新表的匹配记录,就把新表的删了。需要注意的就是假设要加上这句,上面的NOT MATCHED必须加BY TARGET。 6. WHEN MATCHED AND TB_TARGET.VAL2<>TB_SOURCE.VAL1 THEN
UPDATE SET
TB_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_TARGET
USING T1 AS TB_SOURCE
ON TB_TARGET.ID2=TB_SOURCE.ID1
WHEN NOT MATCHED BY TARGET THEN
INSERT(ID2,VAL2)
VALUES(ID1,VAL1)
WHEN NOT MATCHED BY SOURCE THEN
DELETE
WHEN MATCHED AND TB_TARGET.VAL2<>TB_SOURCE.VAL1 THEN
UPDATE SET
TB_TARGET.VAL2=TB_SOURCE.VAL1
OUTPUT $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,VAL1
FROM T1 WHERE NOT EXISTS(
SELECT 1 FROM T2 WHERE T2.ID2=T1.ID1
) UPDATE T2
SET T2.VAL2=T1.VAL1
FROM T2
INNER JOIN T1 ON T2.ID2=T1.ID1
AND T2.VAL2<>T1.VAL1 DELETE 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 次。
*/
使用MERGE语句同步表的更多相关文章
- 如何理解T-SQL中Merge语句(二)
写在前面的话:上一篇写了如何理解T-SQL中Merge语句,基本把Merge语句要讲的给讲了,在文章的后面,抛出了几个结,当时没有想明白怎么去用文字表达,这一篇就来解答一下这几个结,又是一篇“天马行空 ...
- 如何理解T-SQL中Merge语句
写在前面的话:之前看过Merge语句,感觉没什么用,完全可以用其他的方式来替代,最近又看了看Merge语句,确实挺好用,可以少写很多代码,看起来也很紧凑,当然也有别的优点. ====正文开始===== ...
- SQL Server Merge语句的使用
Merge关键字在SQL Server 2008被引入,它能将Insert,Update,Delete简单的并为一句.MSDN对于Merge的解释非常的短小精悍:”根据与源表联接的结果,对目标表执行插 ...
- merge 语句的语法
/*Merge into 详细介绍 MERGE语句是Oracle9i新增的语法,用来合并UPDATE和INSERT语句. 通过MERGE语句,根据一张表或子查询的连接条件对另外一张表进行查询, 连接条 ...
- 使用 MERGE 语句实现增删改
Ø 简介 在平常编写增删改的 SQL 语句时,我们用的最多的就是 INSERT.UPDATE 和 DELETE 语句,这是最基本的增删改语句.其实,SQL Server 中还有另外一个可以实现增删改 ...
- 【转载】SQL Server - 使用 Merge 语句实现表数据之间的对比同步
原文地址:SQL Server - 使用 Merge 语句实现表数据之间的对比同步 表数据之间的同步有很多种实现方式,比如删除然后重新 INSERT,或者写一些其它的分支条件判断再加以 INSERT ...
- 转:SQL Server - 使用 Merge 语句实现表数据之间的对比同步
表数据之间的同步有很多种实现方式,比如删除然后重新 INSERT,或者写一些其它的分支条件判断再加以 INSERT 或者 UPDATE 等.包括在 SSIS Package 中也可以通过 Lookup ...
- SQL Server - 使用 Merge 语句实现表数据之间的对比同步
表数据之间的同步有很多种实现方式,比如删除然后重新 INSERT,或者写一些其它的分支条件判断再加以 INSERT 或者 UPDATE 等.包括在 SSIS Package 中也可以通过 Lookup ...
- Sql server的Merge语句,源表中如果有重复数据会导致执行报错
用过sql server的Merge语句的开发人员都应该很清楚Merge用来做表数据的插入/更新是非常方便的,但是其中有一个问题值得关注,那就是Merge语句中的源表中不能出现重复的数据,我们举例来说 ...
随机推荐
- vue深究第一弹:computed与watch的异同
最近在开发vue的过程中,不断用到了计算属性(computed)和观察者(watch),从逻辑上感觉它们很相似,但是尝试混用它们的时候,又出现了一些问题,那么它们到底有什么异同呢? 1. comput ...
- Git学习笔记 2,GitHub常用命令
廖雪峰Git教程 莫烦Git教程 莫烦Git视频教程 文件三个状态,add之后从工作区(原始状态)到暂存区,commit之后从暂存区到版本库 工作区 暂存区 版本库 unstage stage mas ...
- [SDOI2011]消防(树的直径)
[SDOI2011]消防 题目描述 某个国家有n个城市,这n个城市中任意两个都连通且有唯一一条路径,每条连通两个城市的道路的长度为zi(zi<=1000). 这个国家的人对火焰有超越宇宙的热情, ...
- 01-JS起步
01-JS起步
- Java Web学习总结(20)——基于ZooKeeper的分布式session实现
1. 认识ZooKeeper ZooKeeper-- "动物园管理员".动物园里当然有好多的动物,游客可以根据动物园提供的向导图到不同的场馆观赏各种类型的动物,而不是像走在原始 ...
- Spring Cloud学习笔记【八】服务网关 Zuul(过滤器)
在上篇文章中我们了解了 Spring Cloud Zuul 作为网关所具备的最基本功能:路由(Router),下面我们将关注 Spring Cloud Zuul 的另一核心功能:过滤器(Filter) ...
- JavaScript语言基础3
JavaScript能够处理一些来自于现实世界的数据类型.比如:数字和文本. 同一时候JavaScript中也包括了一些具 有抽象性质的数据类型.比如对象数据类型. JavaScript它是一种弱类 ...
- 《AndroidStudio每日一贴》11. 重构之提炼为常量
提炼为常量是从暂时变量高速提炼出静态常量,这也是我们经常使用的重构手段. 很多其它有用技巧请查看<AndroidStudio有用指南> 操作步骤: ➤ 菜单条: Refactor -> ...
- URAL 1823. Ideal Gas(数学啊 )
题目链接:http://acm.timus.ru/problem.aspx?space=1&num=1823 1823. Ideal Gas Time limit: 0.5 second Me ...
- hdoj--1342--Lotto(dfs)
Lotto Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Subm ...