使用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 次。
*/
时间: 2024-10-10 10:11:55

使用MERGE语句同步表的相关文章

如何理解T-SQL中Merge语句

写在前面的话:之前看过Merge语句,感觉没什么用,完全可以用其他的方式来替代,最近又看了看Merge语句,确实挺好用,可以少写很多代码,看起来也很紧凑,当然也有别的优点. ====正文开始===== SQL Server 2008 引入了Merge关键字,主要是在一条语句里面可以执行insert.update.delete操作,以实现用一个源对象的数据对目标对象数据进行操作.注意这里的”源对象“和”目标对象“我用黑色标注了,源对象和目标对象实际上不仅仅可以是表Table,还可以是临时表.视图.

如何理解T-SQL中Merge语句(二)

写在前面的话:上一篇写了如何理解T-SQL中Merge语句,基本把Merge语句要讲的给讲了,在文章的后面,抛出了几个结,当时没有想明白怎么去用文字表达,这一篇就来解答一下这几个结,又是一篇“天马行空”的文字,大家凑合看吧. ===正文开始=== 先看下面表一(Student_Target)和表二(Student_Source). 一.When Matched部分 执行下面SQL语句: MERGE INTO Student_Target AS st USING Student_Source AS

[Oracle] Merge语句

Merge的语法如下: MERGE [hint] INTO [schema .] table [t_alias] USING [schema .] { table | view | subquery } [t_alias] ON ( condition ) WHEN MATCHED THEN merge_update_clause WHEN NOT MATCHED THEN merge_insert_clause; MERGE是什么,如何使用呢?让我们先看一个简单的需求: 需求是,从T1表更新数

SQL 基础之子查询、多表插入、merge 语句、跟踪一段时间数据变化(二十)

使用子查询处理数据 可以使用子查询中的数据操纵语言(DML)语句: 使用内嵌视图检索数据 从一张表向另一张表复制数据 基于另一张表的值更新表中数据 基于另一张表的值删除表中的行 使用子查询作为数据源检索数据 select department_name, city from departments natural join (select l.location_id, l.city, l.country_id from loc l join countries c on(l.country_id

【转载】SQL Server - 使用 Merge 语句实现表数据之间的对比同步

原文地址:SQL Server - 使用 Merge 语句实现表数据之间的对比同步 表数据之间的同步有很多种实现方式,比如删除然后重新 INSERT,或者写一些其它的分支条件判断再加以 INSERT 或者 UPDATE 等.包括在 SSIS Package 中也可以通过 Lookup, Condition Split 等多种 Task 的组合来实现表数据之间的同步.在这里 "同步" 的意思是指每次执行一段代码的时候能够确保 A 表的数据和 B 表的数据始终相同. 可以通过 SQL Se

Sql server的Merge语句,源表中如果有重复数据会导致执行报错

用过sql server的Merge语句的开发人员都应该很清楚Merge用来做表数据的插入/更新是非常方便的,但是其中有一个问题值得关注,那就是Merge语句中的源表中不能出现重复的数据,我们举例来说明这个问题. 现在我们有一张表叫T_Class_A,其建表语句如下: CREATE TABLE [dbo].[T_Class_A]( [ID] [int] IDENTITY(1,1) NOT NULL, [ClassName] [nvarchar](50) NULL, [StudentTotalCo

Oracle 中MERGE语句的用法(转载)

原文章出处(http://blog.csdn.net/lichkui/article/details/4306299) MERGE语句是Oracle9i新增的语法,用来合并UPDATE和INSERT语句.通过MERGE语句,根据一张表或子查询的连接条件对另外一张表进行查询,连接条件匹配上的进行UPDATE,无法匹配的执行INSERT.这个语法仅需要一次全表扫描就完成了全部工作,执行效率要高于INSERT+UPDATE. //表1create table subs(msid number(9), 

DB2 单张表 merge语句

<span style="font-family: Arial, Helvetica, sans-serif;">merge into CHANNEL_AGENT_PEOPLE_NUMBER_201503 a using (SELECT ? TIME_ID,? CITY_NAME,? NODE_NAME,? NODE_CODE,? PEOPLE_NUMBER, ? VEHICLE_RUNNING_COSTS,? MAIL_TRANSPORT_FEES,? TRAINING_

SQL Server Merge语句的使用

Merge关键字在SQL Server 2008被引入,它能将Insert,Update,Delete简单的并为一句.MSDN对于Merge的解释非常的短小精悍:”根据与源表联接的结果,对目标表执行插入.更新或删除操作.例如,根据在另一个表中找到的差异在一个表中插入.更新或删除行,可以对两个表进行同步.”,通过这个描述,我们可以看出Merge是关于对于两个表之间的数据进行操作的. 可以想象出,需要使用Merge的场景比如: 数据同步 数据转换 基于源表对目标表做Insert,Update,Del