读书人

sql2008使用merge语句实现数据差异传输

发布时间: 2012-01-19 00:22:28 作者: rapoo

sql2008使用merge语句实现数据差异传输
最近数据库升级到2008,研究了一下,发现有一个很好用的新功能,merge 语句加上存储过程,可以实现数据的差异传输,源表的增删改,都可以使用 merge 语句,把数据更改应用到目标表上,我们原来一个2亿多条记录的表,完全传输一次需要3个多小时,使用这个方法进行数据传输,首次花的时间和原来差不多,但是在以后的每次的作业里面,看到传输时间只有不到 10分钟了,经大量数据抽样检查,数据是完全相同的,通过优化,还可以增加作业的频率,实现数据更短的时间差,这对于表比较大,而且需要进行不定期同步的情况来说,节省了不少时间,当然,数据库镜像 和 数据发布订阅也能解决这个问题,但是对应用比较简单,数据同步实时性要求不到,数据量巨大的情况,这个方法部署起来还是相对简单一些的,呵呵


这个方法非常实用,发出来让大家分享一下,也欢迎各位大侠提出更好的解决办法


1:先在目标服务器上建立一个到源服务器的链接服务器,名字 xx2008(比较简单,不详细说了)

2:在表里面,增加一个字段 updatetime,记录数据更新时间,同时表里面要有 id 自动增加字段

3:以原库名 c_001 , t_001 表为例,以在目标服务器上建立存储过程(这是例程,要提高效率的话,还可以优化过程)

4:建立作业,定时调用存储过程


SQL code
 
Create PROCEDURE [dbo].[backup_001]

AS
BEGIN

SET NOCOUNT ON;

SET IDENTITY_Insert t_001 ON
merge t_001 d
using
(SELECT * FROM OPENQUERY (xx2008 ,'select * from c_001.dbo.t_001' ) ) s
on (d.id=s.id and d.updatetime <>s.updatetime)
WHEN NOT MATCHED BY SOURCE THENdelete
when matched then
update set
d.f1=s.f1,
d.f2=s.f2,
d.f3=s.f3,
......
d.updatetime=s.updatetime
when not matched then
insert (d.f1,d.f2,d.f3,......d.updatetime)
values (s.f1,s.f2,s.f3,......s.updatetime);
SET IDENTITY_Insert t_001 OFF




END




[解决办法]
学习.
[解决办法]
不错。。


[解决办法]
半地下研究下
[解决办法]
。。。。。。。。。。。。。
[解决办法]
我也贴俩,凑凑热闹

SQL code
--merge主要用于两表之间的关联操作 有两张结构一致的表:test1,test2create 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')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*/
[解决办法]
路过。
[解决办法]
SQL code
IF OBJECT_ID (N'dbo.Departments', N'U') IS NOT NULL     DROP TABLE dbo.Departments;GOCREATE TABLE dbo.Departments (DeptID tinyint NOT NULL PRIMARY KEY, DeptName nvarchar(30),     Manager nvarchar(50));GOINSERT INTO dbo.Departments     VALUES (1, 'Human Resources', 'Margheim'),(2, 'Sales', 'Byham'),            (3, 'Finance', 'Gill'),(4, 'Purchasing', 'Barber'),           (5, 'Manufacturing', 'Brewer');GOSELECT * FROM dbo.Departments GOIF OBJECT_ID (N'dbo.Departments_delta', N'U') IS NOT NULL     DROP TABLE dbo.Departments_delta;GOCREATE TABLE dbo.Departments_delta (DeptID tinyint NOT NULL PRIMARY KEY, DeptName nvarchar(30),     Manager nvarchar(50));GOINSERT INTO dbo.Departments_delta VALUES     (1, 'Human Resources', 'Margheim'), (2, 'Sales', 'Erickson'),    (3 , 'Accounting', 'Varkey'),(4, 'Purchasing', 'Barber'),     (6, 'Production', 'Jones'), (7, 'Customer Relations', 'Smith');GOSELECT * FROM dbo.Departments_deltaGOMERGE dbo.Departments 


[解决办法]
学习,谢谢楼主
[解决办法]
恩 不错 不错不错
[解决办法]
研究研究
[解决办法]
研究研究
[解决办法]
不错 正在学习中
[解决办法]
好东西啊。
[解决办法]

[解决办法]
每天回帖即可获得10分可用分!
[解决办法]
学习中

[解决办法]
....
merge语句,貌似05就有了
[解决办法]
learning......
[解决办法]
学写了。
[解决办法]

探讨
我还有一个问题,如何通过参数,让这个存储过程能适应所有的表,现在这个方法还是要根据每个表的不同,需要单独建立存储过程,这点比较繁复,有没有更好的方法,能使用在所有的表上呢,解决的另外还有高分相赠

[解决办法]
感谢分享
[解决办法]
查找........
[解决办法]
Create PROCEDURE [dbo].[backup_001]

AS
BEGIN

SET NOCOUNT ON;

SET IDENTITY_Insert t_001 ON
merge t_001 d
using
(SELECT * FROM OPENQUERY (xx2008 ,'select * from c_001.dbo.t_001' ) ) s
on (d.id=s.id and d.updatetime<>s.updatetime)
WHEN NOT MATCHED BY SOURCE THEN delete
when matched then
update set
d.f1=s.f1,
d.f2=s.f2,
d.f3=s.f3,
......
d.updatetime=s.updatetime
when not matched then
insert (d.f1,d.f2,d.f3,......d.updatetime)
values (s.f1,s.f2,s.f3,......s.updatetime);
SET IDENTITY_Insert t_001 OFF




END


[解决办法]
学习学习~本人刚接触2008,不知道哪位能提供点参考资料学习学习呢?
[解决办法]
这样就行了啊???
[解决办法]
学习一下
[解决办法]
最近在写PLSQL用过
[解决办法]
merge早在oracle使用来做数据合并了
[解决办法]
MARK 一下!
[解决办法]
学习了
[解决办法]
好资料,学习学习.
[解决办法]
学习。。。
[解决办法]
哎,仍在用SQL2000
------解决方案--------------------


探讨
最近数据库升级到2008,研究了一下,发现有一个很好用的新功能,merge 语句加上存储过程,可以实现数据的差异传输,源表的增删改,都可以使用 merge 语句,把数据更改应用到目标表上,我们原来一个2亿多条记录的表,完全传输一次需要3个多小时,使用这个方法进行数据传输,首次花的时间和原来差不多,但是在以后的每次的作业里面,看到传输时间只有不到 10分钟了,经大量数据抽样检查,数据是完全相同的,通……

[解决办法]
不错的分享 顶~
[解决办法]
我也刚下的server 2008 很不错啊 好
[解决办法]
好东西
[解决办法]
LZ 问你个问题,用merge 必须要求表结构一致吗?
[解决办法]
探讨

以前也整理了一篇,贴出来交流一下:SQL2008 Merge关键字用法与简例

[解决办法]
学习,接分
[解决办法]
不喜欢go这个词
[解决办法]
牛人,帖子内容不错,顶一个!!!
[解决办法]


[解决办法]

[解决办法]
好。真不错啊 想当可以啊
[解决办法]
号不错 真可以啊
[解决办法]
很强大。。。。。。。
[解决办法]
不错 学习了 出来看看长点见识 还用2000中
[解决办法]
精神可嘉,谢谢分享知识。
收藏下,以后也许会用到。
[解决办法]
Oracle下merge用法:
oracle-merge用法详解:
http://jinjiabao.javaeye.com/blog/481477
[解决办法]
学习了
[解决办法]
恩,先记下了

1:先在目标服务器上建立一个到源服务器的链接服务器,名字 xx2008(比较简单,不详细说了)

2:在表里面,增加一个字段 updatetime,记录数据更新时间,同时表里面要有 id 自动增加字段

3:以原库名 c_001 , t_001 表为例,以在目标服务器上建立存储过程(这是例程,要提高效率的话,还可以优化过程)

4:建立作业,定时调用存储过程
[解决办法]
merge稍微复杂,还有点嗦。写出来的东西可读性不是很强。
但性能比if exists好点.
[解决办法]
学习一下Mark
[解决办法]
标记一下,2008新东西,也许以后用得到,谢谢分享!
[解决办法]
好东西 学习了
[解决办法]
谢谢楼主

读书人网 >SQL Server

热点推荐