使用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语句中的源表中不能出现重复的数据,我们举例来说 ...
随机推荐
- jumpserver 安装python 报错
环境centos7.5 pip3 insatll ./python-gssapi-0.6.4.tar.gz 报错 Command "python setup.py egg_info&quo ...
- Log4j2打印一行日志时返回本行日志的字符串
import org.apache.logging.log4j.Level; import org.apache.logging.log4j.core.impl.Log4jLogEvent; impo ...
- CsGL着色的三角形
转自NeHe教程 public override void Draw() { // Here's Where We Do All The Drawing glClear(GL_COLOR_BUFFER ...
- Activity 中的Toast在Activity销毁后报错,解决方法,把context改成应用的
ToastUtil.showShort(context, R.string.connection_fail); 改成 ToastUtil.showShort(BusinesslinkApplicati ...
- Git简介以及与SVN的区别
Git是由著名Linux内核(Kernel)开发者LinusTorvalds为了便利维护Linux而开发的. Git是一个分布式的版本控制系统.作为一个分布式的版本控制系统,在Git中并不存在主库这样 ...
- 85.explicit作用
#include <iostream> using namespace std; class myclass { public: int num; public: explicit myc ...
- HDU 5358 First One 数学+尺取法
多校的题,摆明了数学题,但是没想出来,蠢爆了,之前算了半天的s[i][j]的和,其实是积.其实比赛的时候我连log(s[i][j])+1是s[i][j]的位数都没看出来,说出来都丢人. 知道了这个之后 ...
- OpenGL编程逐步深入(一)创建一个窗口
原文地址:http://ogldev.atspace.co.uk/ 原文中使用gnu make进行项目管理,本系列文章使用visual studio2012.在翻译过程中并非直译,加入了一些笔者个人观 ...
- Vue官方文档中的camelCased (驼峰式) 命名与 kebab-case
因为html特性中 元素的 prop是不区分大小写的 所以不管html中怎么大写小写变化,下面的组件的prop应该写成小写 Vue中有这样一种设定: props中如果使用为kebab-case命名方式 ...
- 学习推荐《从Excel到Python数据分析进阶指南》高清中文版PDF
Excel是数据分析中最常用的工具,本书通过Python与Excel的功能对比介绍如何使用Python通过函数式编程完成Excel中的数据处理及分析工作.在Python中pandas库用于数据处理,我 ...