请问腾米跑跑官网怎样数据同步

数据同步程序说明文档_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
数据同步程序说明文档
上传于||文档简介
&&数​据​同​步​程​序​说​明
阅读已结束,如果下载本文需要使用1下载券
想免费下载本文?
定制HR最喜欢的简历
下载文档到电脑,查找使用更方便
还剩2页未读,继续阅读
定制HR最喜欢的简历
你可能喜欢腾米跑跑王齐:智能手表更容易被用户接受
来源:腾讯视频
腾讯科技讯(陶然)北京时间4月28日-29日,全球移动互联网大会(GMIC)在北京-国家会议中心举行。作为腾讯TOS智能手表第一批开发者,腾米跑跑CEO王齐接受了腾讯科技专访。王齐表示,智能手表相比其他智能设备更容易被接受,因为它有更好、更丰富的交互界面,也能获得更好的生理数据,更稳定的运动数据。同时她认为,“伴随着腾讯这样的公司一起来前行,会比自己摸索方向成本低很多”。作为跑步类应用,王齐表示,“未来腾米跑跑会基于跑步继续扩大,通过各种各样的方式让大家来参与,包括互联网赛事、马拉松赛事等,用互联网便捷的方式把传统的东西变得更快捷、更方便”。以下是腾米跑跑CEO王齐专访实录腾讯科技:非常高兴能在CMIC大会上邀请到腾米跑跑CEO王齐作客腾讯科技,首先请您介绍一下腾米跑跑,为什么选择这个方向创业?王齐:我自己是腾讯第12号员工,在腾讯工作14年,腾米跑跑也是取自于Tencent的谐音,Ten minute 10分钟,就是说每天保持10分钟运动时间会让你的生活更加不一样,所以取了这样的一个名字。为什么选择运动的方向纯属是自己的个人爱好。因为腾讯工作这么久很多人觉得你可以休息,环游世界了,但是出来以后自己锻炼身体发现我们这个行业的人真的很需要运动。我实验了几款运动软件,发现这些APP各有自己的缺点,我们腾讯人可能是想自己做产品,一直都有这种情结在。所以就找了一些人,我的团队基本都是来自于老腾讯人,所以想做这样一款运动的产品,具有我们自己的特色,具有腾讯产品基因这样的一款产品。纯属是因为兴趣,想做一款属于我们自己的产品。腾讯科技:现在市面上运动类、生活方式类的AAP很多,为什么选择跑步这个的方向聚焦?王齐:你可以选择方向很多,但是跑步更加容易切入,不光是专业选手,你只要有一双鞋就可以,一双鞋可以就跑起来。所以这个人群也是比较垂直的,但是人群也是最大的一个人群。未来我们会基于跑步上扩大,会有各种各样的方式让大家来参与,甚至包括互联网赛事、马拉松赛事,用互联网便捷的方式把传统的东西变得更快捷、更方便、这是我们的方向。腾讯科技:今天腾讯TOS要发智能手表,您觉得围绕智能手表APP未来会有什么趋势?王齐:很荣幸腾米跑跑成为第一批开发者,当时找我们的时候我们觉得这是一个非常好的方向。因为智能手表领域现在来说是一个比较新的领域,随着国外像、()、国内腾讯这样巨头的介入,他们的推动一定比其他的一般企业的推动和思考会更深刻。所以伴随着腾讯这样的巨头,我们一起来前行会比我们自己摸索方向成本低很多。趋势上来说,作为开发者来讲,我们可能不太关注手表未来会长什么样子,因为随着记忆、材质以及流程飞速发展,这个行业一定是很蓬勃的,对于开发者来讲,更多的是专注于我们的产品打磨上给用户带来更好的体验。其实智能手表领域它是比其他的智能设备更加让大家能够接受的。因为它跟手环相比有更好、更丰富的交互界面,包括它能获得更好的生理数据,更稳定的运动数据。所以我觉得它是会比其他的智能设备来说,让用户更能接受的。基于在这个手表传感器的基础上,我们的开发会越来越丰富,越来越垂直化。腾讯科技:腾米跑跑要做的就是产品开发,app这一块,不会自己做智能硬件?王齐:对。我们的观点还是做自己更擅长的事情,我的团队包括腾米跑跑更专注软件,我们是想把运动切入到人们生活的方方面面。硬件我们只是结合硬件做一个生态化,这样的一个运动生态链,不管是手表,还有其他的设备,我们还接了手环和跑鞋,是把这些数据孤岛都打通。腾讯科技:今年有一个热词就是“互联网+”,您怎么看的?有些人认为线上更重要,有些人认为是线下更重要?王齐:我认为线上线下都很重要缺一不可。腾讯科技:您作为腾讯第12号员工,对创业您怎么理解的,包括很多人认为现在创业有泡沫,您怎么看?王齐:现在很热的一句话说,这是一个最好的时代,也是一个最差的时代,为什么说最好的时代呢?因为现在国家倡导都要求全民创业化。我了解到的包括我们招人挺难的,很多大学生、很多好的人才自己都创业了,这是一个很好的支持创业的年代。最差的年代就是因为,其实分分钟都可能有创业公司倒闭,创业项目在失败。但是我还会坚持一个创业的理念,其实创业是有机会让你的梦想去实现的。你有什么好的想法可以通过创业去实现,有句话叫梦想还是要有的,万一实现了呢。创业还是要谨慎的,我比较倡导现在的年轻人需要经过一些系统的训练,特别是在大公司的系统训练以后再去经历创业的里程。腾讯科技:非常感谢您接受腾讯科技的采访。
[责任编辑:huitangdu]
您认为这篇文章与"新一网(08008.HK)"相关度高吗?
Copyright & 1998 - 2016 Tencent. All Rights Reserved
还能输入140字关于数据同步的几种实现 - 星星之火116 - 博客园
燎原之势不可挡
posts - 114, comments - 358, trackbacks - 0, articles - 3
关于数据同步的几种实现
关于数据同步主要有两个层面的同步,一是通过后台程序编码实现数据同步,二是直接作用于数据库,在数据库层面实现数据的同步。通过程序编码实现数据同步,其主要的实现思路很容易理解,即有就更新,无则新增,其他情况日志记录,就不做过多的介绍,这里主要讲述的是第二个层面的数据同步,即在数据库层面实现数据同步。
数据库层面的数据库同步主要有三种方式:通过发布/订阅的方式实现同步,通过SQL JOB方式实现数据同步,通过Service Broker 消息队列的方式实现数据同步。
下面分别就这三种数据同步方式,一一详解。
1.&&& 通过发布/订阅的方式实现同步
发布/订阅是Sql Server自带的一种数据库备份的机制,通过该机制可以快速的实现数据的备份同步,不用编写任何的代码。
此种数据同步的方式存在的以下的一些问题:
表结构不能更改,同步双方的表结构必须一致,一旦表结构发生更改需要重新生成数据库快照。
对于大数据量的同步没有可靠的保证。
网络不稳定的情况下同步也不能保证。
总的来说,这种数据备份同步的方式,在表结构一致、数据量不是特别大的情况下还是非常高效的一种同步方式。
网上有很多的关于如何使用发布/订阅的方式实现数据同步的操作示例,这里就不再重复的演示了,有兴趣想要了解的朋友可以参考下面这篇文章:
2.&&& 通过SQL JOB方式实现数据同步
通过Sql Job定时作业的方式实现同步其基本原理就是通过目标服务器和源服务器的连接,然后通过编写Sql语句,从源服务器中读取数据,再更新到目标服务器。
这种数据同步的方式比较灵活。创建过sql定时作业之后,主要需要执行以下关键的两步。
2.1&&&& 创建数据库连接(一般作为定时作业执行的第一步)
不同数据库之间的连接可以通过系统的存储过程实现。下面就直接用一个示例来讲一下如何创建数据库连接。
--添加一个连接
--系统存储过程sp_addlinkedserver 参数:
----------------------1:目标服务器的IP或别名,本例中为:'WIN-S1PO3UA6J7I';----------------------2:'' (srvproduct,默认);
----------------------3:'SQLOLEDB'(provider,默认值);
----------------------4:目标服务器的IP或别名(datasrc),本例中为:'WIN-S1PO3UA6J7I'
exec sp_addlinkedserver 'WIN-S1PO3UA6J7I','','SQLOLEDB','WIN-S1PO3UA6J7I'
--添加登录用户连接
--系统存储过程sp_addlinkedsrvlogin 参数:
----------------------1:目标服务器的IP或别名,本例中为:'WIN-S1PO3UA6J7I';
----------------------2:'false',默认值;
----------------------3:null,默认值;
----------------------4:'sa',登录用户名;
----------------------5:'pass@word1',登录密码;
exec sp_addlinkedsrvlogin 'WIN-S1PO3UA6J7I','false',null,'sa','pass@word1'
创建数据库连接主要用到了以上的两个存储过程,但是在实际操作的过程中可能会遇到&仍有对服务器XXX的远程登录或连接登录问题&这样的问题,如果遇到此类问题,在执行上边的添加连接和登录用户连接之前还需要先删除某个已存在的链接,具体如下:
--系统存储过程sp_droplinkedsrvlogin 参数:
----------------------1:目标服务器的IP或别名,本例中为:'WIN-S1PO3UA6J7I';----------------------2:null
exec sp_droplinkedsrvlogin 'WIN-S1PO3UA6J7I',null
--系统存储过程sp_dropserver 参数:
----------------------1:目标服务器的IP或别名,本例中为:'WIN-S1PO3UA6J7I'
exec sp_dropserver 'WIN-S1PO3UA6J7I'
2.2&&&& 使用SQL 语句 实现数据同步
主要的同步思路:
1:在目标数据库中先清空要同步的表的数据
2:使用insert into Table (Cloumn....) select Column..... from 服务器别名或IP.目标数据库名.dbo.TableName 的语法将数据从源数据库读取并插入到目标数据库
Truncate &table &Org_DepartmentsExt &删除现有系统中已存在的部门表
insert into Org_DepartmentsExt &从名为WIN-S1PO3UA6J7I的服务器上的DBFrom数据库上获取源数据,并同步到目标数据库中
&&&&& [DeptID]
&&&&& ,[DeptStatus]
&&&&& ,[DeptTel]
&&&&& ,[DeptBrief]
&&&&& ,[DeptFunctions]&
SELECT [DeptID]
&&&&& ,[DeptStatus]
&&&&& ,[DeptTel]
&&&&& ,[DeptBrief]
&&&&& ,[DeptFunctions]
& FROM [WIN-S1PO3UA6J7I].[DBFrom].[dbo].[Org_DepartmentsExt]
以上这两步便是通过SQL Job实现数据同步的关键步骤,在完成以上两步之后,如果没有其他的表要进行同步,则可创建同步计划以完善定时作业。带作业创建完后,便可以执行。
这里主要只是演示了通过Sql Job方式实现数据同步的关键步骤。网上有很多具体的实例演示。有兴趣的朋友可以参考以下文章进行练习检验:
3.&&& 通过SQL Server Service Broker 消息队列的方式实现数据同步
3.1 SQL Server Service Broker概述
SQL Server Service Broker 是数据库引擎的组成部分,为 SQL Server 提供队列和可靠的消息传递。既可用于使用单个 SQL Server 实例的应用程序,也可用于在多个实例间分发工作的应用程序。
在单个 SQL Server 实例内,Service Broker 提供了一个功能强大的异步编程模型。数据库应用程序通常使用异步编程来缩短交互式响应时间,并增加应用程序总吞吐量。
在多个SQL Server实例之间Service Broker 还可以提供可靠的消息传递服务。Service Broker 可帮助开发人员通过称为服务的独立、自包含的组件来编写应用程序。需要使用这些服务中所包含功能的应用程序可以使用消息来与这些服务进行交互。Service Broker 使用 TCP/IP 在实例间交换消息。Service Broker 中所包含的功能有助于防止未经授权的网络访问,并可以对通过网络发送的消息进行加密。
3.2 具体的实现演示
在这一小节里,主要是通过一个完整的数据同步的流程向大家演示,如何实现同一个数据库实例不同数据库的数据同步。关于不同的数据库实例间的数据库的数据同步整体上跟同一个实例的数据库同步是一样的,只不过在不同的数据库实例间同步时还需启用传输安全、对话安全,创建路由、远程服务绑定等额外的操作。
这里边用到了大量的SQL Server XML的东西,如果有不理解的地方可以参考以下链接:
这是我在做技术准备时,自己的一点学习记录。
下面就是具体的实现步骤:
3.2.1为数据库启动Service Broker活动
&&& 这一步主要是用来对要进行数据同步的数据启用Service Broker 活动,并且授信。
USE master
--如果数据库DBFrom、DBTo不存在,则创建相应的数据库
IF NOT EXISTS (SELECT name FROM sys.databases WHERE name ='DBFrom')
CREATE DATABASE DBFrom
IF NOT EXISTS (SELECT name FROM sys.databases WHERE name ='DBTo')
CREATE DATABASE DBTo
--分别为该数据库启用Service Broker活动并且授权信任
ALTER DATABASE DBFrom SET ENABLE_BROKER
ALTER DATABASE DBFrom SET TRUSTWORTHY ON
ALTER AUTHORIZATION ON DATABASE::DBFrom To sa
ALTER DATABASE DBTo SET ENABLE_BROKER
ALTER DATABASE DBTo SET TRUSTWORTHY ON
ALTER AUTHORIZATION ON DATABASE::DBTo TO sa
3.2.2 创建数据库主密匙
这一步主要用来创建数据库主密匙,上边有提到Service Broker可以对要发送的消息进行加密。
Use DBFrom
create master key
encryption by password='pass@word1'
create master key
encryption by password='pass@word1'
3.2.3 创建消息类型、协定
这里主要用来创建消息类型和消息协定,源数据库和目标数据库的消息类型和协定都要一致。
Use DBFrom
--数据同步&消息类型
create message type [/Data/Sync]
validation=well_formed_xml
--数据同步--错误反馈消息类型
create message type [/Data/Sync/Error]
validation=well_formed_xml
--数据同步协议
create contract[/Data/SyncContract]
[/Data/Sync]
sent by initiator,
[/Data/Sync/Error]
sent by target
--数据同步&消息类型
create message type [/Data/Sync]
validation=well_formed_xml
--数据同步--错误反馈消息类型
create message type [/Data/Sync/Error]
validation=well_formed_xml
--数据同步协议
create contract[/Data/SyncContract]
[/Data/Sync]
sent by initiator,
[/Data/Sync/Error]
sent by target
创建过之后效果如下图:
& & & & & & & & & & & &
3.2.4 创建消息队列
&&& 这里主要用来创建消息队列,源数据库和目标数据库都要创建,队列名字可以自主命名。
use DBFrom
create queue [DBFrom_DataSyncQueue]
with status=on
create queue [DBFrom_DataSyncQueue]
with status=on
创建之后效果如下图:
3.2.5 创建数据同步服务
这里我们通过利用上边创建的消息协定和消息队列来创建数据同步的服务。
use DBFrom
create service [/DBFrom/Data/SyncService]
on queue dbo.[DBFrom_DataSyncQueue]([/Data/SyncContract])
--数据同步服务
create service [/DBTo/Data/SyncService]
on queue dbo.[DBFrom_DataSyncQueue]([/Data/SyncContract])
&&& 创建后效果如下图:
3.2.6 在源数据库上创建服务配置列表
这里需要在源数据库上创建一个服务配置列表,主要用来保存之前创建过的服务名称,本例只是用来演示,所以只创建了一个服务,只能是同步一个数据表,如果有多个数据表需要同步,则需创建多个服务,所以这里创建一个服务配置列表,用来存储多个服务的服务名称。
需要注意的是,下面的脚本在执行完创建表的操作之后又插入了一条数据,也就是上边我们创建的服务名,如果有多个服务的话,依次插入该表即可。
use DBFrom
--同步数据--目标服务配置
create table SyncDataFarServices
ServiceID uniqueidentifier,
ServiceName nvarchar(256)
--将上边创建的服务名,插入此表中
insert into SyncDataFarServices (ServiceID,ServiceName)
(NEWID(),'/DBTo/Data/SyncService')
效果如下图:
3.2.7 发送数据同步消息
&&& 这里创建了一个存储过程主要用来发送同步消息,该消息内容主要包括操作类型、主键、表名、正文内容,分别对应@DMLType,@PrimaryKeyField,@TableName,@XMLData。然后通过创建一个游标来条的读取上边创建的服务列表中的列表信息,向不同的服务发送消息。
Use DBFrom
--发送同步数据消息
Create procedure UP_SyncDataSendMsg
@PrimaryKeyField nvarchar(128),
@TableName nvarchar(128),
@DMLType char(1),
@XMLData xml
SET @XMLData.modify('insert &DMLType&{sql:variable("@DMLType")}&/DMLType&
as first into /');
SET @XMLData.modify('insert &PrimaryKeyField&{sql:variable("@PrimaryKeyField")}&/PrimaryKeyField&
as first into /');
SET @XMLData.modify('insert &Table&{sql:variable("@TableName")}&/Table& as first into /');
DECLARE FarServices CURSOR FOR SELECT ServiceName FROM SyncDataFarS
open FarServices
declare @FarServiceName nvarchar(256);
fetch FarServices into @FarServiceN
while @@FETCH_STATUS=0
begin Transaction
declare @Conv_Handler uniqueidentifier
begin DIALOG conversation @Conv_Handler --开始一个会话
from service [/DBFrom/Data/SyncService]
to service @FarServiceName
on contract [/Data/SyncContract];
send on conversation @Conv_Handler
Message type [/Data/Sync](@XMLData);
fetch FarServices into @FarServiceN
close FarS
deallocate FarS
3.2.8 创建数据同步异常信息记录表
这里创建该表主要用来记录在数据同步过程中出现的异常信息。
use DBFrom
create Table dbo.SyncException
ErrorID uniqueidentifier,
ConversationHandleID uniqueidentifier,
ErrorNumber int,
ErrorSeverity int,
ErrorState int,
ErrorProcedure nvarchar(126),
ErrorLine int,
ErrorMessage nvarchar(2048),
MessageContent nvarchar(max),
CreateDate DateTime
--修改异常信息记录表
alter table dbo.SyncException
PrimaryKeyField nvarchar(128),
TableName nvarchar(128),
DMLType char(1),
DBName nvarchar(128)
效果如下图:
3.2.9 数据同步反馈
这里主要用来在源数据库中接收队列中的消息,将同时出错的信息,解析一下,然后插入到异常信息记录表里边。
--数据同步回馈
use DBFrom
create procedure UP_SyncDataFeedback
set nocount on
--会话变量声明
declare @ConversationHan--会话句柄
declare @Msg_Body nvarchar(max);
declare @Msg_Type_N
--变量赋值
while(1=1)
begin transaction
--从队列中接收消息
receive top(1)
@Msg_Type_Name=message_type_name,
@ConversationHandle=[conversation_handle],
@Msg_Body=message_body
from dbo.[DBFrom_DataSyncQueue]
),timeout 1000
--如果接收到消息处理,否则跳过
if(@@ROWCOUNT&=0)
if @Msg_Type_Name='/SQL/ServiceBroker/EndDialog'
end conversation @ConversationH
else if @Msg_Type_Name='/Data/Sync/Error'
declare @DataS
set @DataSource=Convert(xml,@Msg_Body);
insert into dbo.SyncException(ErrorID,ConversationHandleID,ErrorNumber,ErrorSeverity,ErrorState,ErrorProcedure,ErrorLine,ErrorMessage,PrimaryKeyField,TableName,DMLType,MessageContent,DBName,CreateDate)
NEWID(),@ConversationHandle,
T.c.value('./@ErrNumber','INT'),
T.c.value('./@ErrSeverity','INT'),
T.c.value('./@ErrState','INT'),
T.c.value('./@ErrProcedure','Nvarchar(126)'),
T.c.value('./@ErrLine','INT'),
T.c.value('./@ErrMessage','nvarchar(2048)'),
T.c.value('./@PrimaryKeyField','nvarchar(128)'),
T.c.value('./@TableName','nvarchar(128)'),
T.c.value('./@DMLType','char(1)'),
T.c.value('./@MessageContent','nvarchar(max)'),
T.c.value('./@DBName','nvarchar(128)'),
from @DataSource.nodes('/row') as T(c);
else if @Msg_Type_Name='/SQL/ServiceBroker/Error'
end conversation @ConversationH
3.2.10对Service Broker队列使用内部激活,并指定将调用的存储过程
&&& 这里主要用来激活源数据库的消息队列,并为其指定调用的存储过程,即上边3.2.9 中创建的存储过程。
--对Service Broker队列使用内部激活,并指定将调用的存储过程
use DBFrom
alter queue dbo.DBFrom_DataSyncQueue with activation
status=on,
max_queue_Readers=1,
procedure_name=UP_SyncDataFeedback,
execute as owner
3.2.11 在源数据库中为需要同步的数据表创建触发器
这里就以用户表为例,具体操作如下,这里通过查询系统的Inserted和Deleted临时表来判断执行同步的操作类型是更新(U)、新增(A)还是删除(D),最后调用3.2.7 中创建的存储过程来对数据进行处理并发送。
use DBFrom
--用户信息同步
Create Trigger UT_DataSync_Users
on dbo.Org_Users
after insert,update,delete
--变量声明
declare @PrimaryKeyField nvarchar(128),@TableName nvarchar(128),@DMLType char(1);
declare @InsertCount int ,@DeleteC
declare @XMLD
--变量赋值
set @PrimaryKeyField='ID' --组合主键,多个主键使用","隔开
set @TableName='Org_Users'
set @InsertCount=(select COUNT(*) from inserted)
set @DeleteCount=(select COUNT(*) from deleted)
if @InsertCount=@DeleteCount and @InsertCount&&0
----Update
select @XMLData=(select * from inserted For xml raw,binary base64,ELEMENTS XSINIL);
set @DMLType='U';
else if(@InsertCount&&0 and @DeleteCount=0) ----Insert
select @XMLData=(select * from inserted for xml raw ,Binary base64,ELEMENTS XSINIL)
set @DMLType='A';
else----Delete
select @XMLData=(select *from deleted for xml raw,binary base64,ELEMENTS XSINIL)
set @DMLType='D';
if(@XMLData is not null)
exec UP_SyncDataSendMsg @PrimaryKeyField,@TableName,@DMLType,@XMLD
3.2.12 目标数据库中创建,字符分割函数
该函数主要是用来进行字符分割,用来处理主键有多个字段的情况。
--目标数据库
--转换用&,'分割的字符串@str
create Function dbo.uf_SplitString
@str nvarchar(max),
@Separator nchar(1)=','
returns nvarchar(2000)
declare @F--结果字段列表
declare @N-----记录循环次数
declare @P-----记录开始搜索位置
declare @NextP--搜索位置临时变量
declare @FieldValue nvarchar(256);--搜索结果
set @Num=0;
set @Pos=1;
set @Fields=CONVERT(xml,'&Fields&&/Fields&');
while (@Pos&=LEN(@Str))
select @NextPos=CHARINDEX(@Separator,@Str,@Pos)
if(@NextPos=0 OR @NextPos is null)
select @NextPos=LEN(@Str)+1;
select @FieldValue=RTRIM(ltrim(substring(@Str,@Pos,@NextPos-@Pos)))
select @Pos=@NextPos+1
set @Num=@Num+1;
if @FieldValue&& ''
set @Fields.modify('insert &Field&{sql:variable("@FieldValue")}&/Field& as last into /Fields[1]');
return Convert(nvarchar(2000),@Fields);
3.2.13 将解析过的消息信息,根据操作类型的不同同步到数据表中
&&& 这是所有的数据同步中最关键也是最复杂的一步了,在整个开发的过程中,大部分时间都花在这上边了,具体的操作都在下面解释的很清楚了。
--将XML数据源中的数据同步到数据表中(包括增删改)
create function dbo.UF_XMLDataSourceToSQL
@DataSource XML,--数据源
@TableName varchar(128),--同步数据表名称
@PrimaryKeyField varchar(128),--需要同步的表的主键,主键为多个时用&,'隔开
@DMLType char(1) --A:新建;U:编辑;D:删除
returns nvarchar(4000)
--变量声明及数据初始化
--声明数据表@TableName列Column相关信息变量
declare @ColumnName nvarchar(128),@DataType nvarchar(128),@MaxL
--声明用于拼接SQL的变量
declare @FieldsList nvarchar(4000),@QueryStatement nvarchar(4000);
declare @Sql nvarchar(4000);
declare @StrL
--变量初始化
set @FieldsList='
';--初始化变量不为null,否则对变量使用'+='操作符无效
set @QueryStatement='
--主键信息,根据参数求解如:&Fields&&Field&ID1&/Field&&Field&ID2&/Field&&/Fields&
declare @PK
--当前字段是否主键-在&更新&,&删除&同步数据时使用
declare @IsPK nvarchar(128);
--初始化游标--游标内容包括目标数据表TableName列信息
DECLARE ColumnNameList CURSOR FOR SELECT COLUMN_NAME,DATA_TYPE,CHARACTER_MAXIMUM_LENGTH FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME=@TableName AND DATA_TYPE&&'xml';
--数据处理
if @DMLType='A'--插入数据
open ColumnNameList
fetch ColumnNameList into @ColumnName,@DataType,@MaxL
while @@FETCH_STATUS=0
--判断数据源列中是否存在属性:@ColumnName
--判断数据源列中是否存在--元素:@ColumnName
If @DataSource.exist('/row/*[local-name()=sql:variable("@ColumnName")]')=1
set @FieldsList+=(@ColumnName+',');
set @QueryStatement+=('T.c.value(''(./'+@ColumnName+'[not(@xsi:nil)])[1]'','''+@DataType);--元素读取(包含空值情况)
if @MaxLength is not null and @MaxLength&&-1
set @QueryStatement+='('+CONVERT(nvarchar,@MaxLength)+')';
else if @MaxLength=-1 and @DataType&&'xml'--已调整
set @QueryStatement+='(MAX)';
set @QueryStatement+=(''') as '+@ColumnName+',');
fetch ColumnNameList into @ColumnName,@DataType,@MaxLength
close ColumnNameL
deallocate ColumnNameL
set @StrLength=LEN(@FieldsList);
--去掉@FieldsList结尾的&,'
set @FieldsList=SUBSTRING(@FieldsList,1,@StrLength-1);
set @StrLength=LEN(@QueryStatement);
--去掉@QueryStatement结尾的&,'
set @QueryStatement=SUBSTRING(@QueryStatement,1,@StrLength-1);
set @Sql=N'insert into '+@TableName+'('+@FieldsList+') select '+@QueryStatement+' from @DataSource.nodes(''/row/'') as T(c)';
else if @DMLType='U'--更新数据
--更新语句where 后的条件表达式
declare @Condition nvarchar(1000);
set @Condition='
set @PKs=CONVERT(xml,dbo.uf_SplitString(@PrimaryKeyField,','));
Open ColumnNameList
fetch ColumnNameList into @ColumnName,@DataType,@MaxL
while @@FETCH_STATUS=0
--判断数据源列中是否存在元素:@ColumnName
if @DataSource.exist('/row/*[local-name()=sql:variable("@ColumnName")]')=1
set @IsPK=
SELECT @IsPk=Fs.F FROM (SELECT T.c.value('.[text()]','Nvarchar(128)') AS F FROM @PKs.nodes('/Fields/Field') AS T(c))Fs Where Fs.F=@ColumnName
if @IsPK is null or @IsPK=''
--非主键,更新字段值
set @FieldsList+=(@ColumnName+'=Source.'+@ColumnName+',');
--主键,作为要更新条件
set @Condition+=@TableName+'.'+@ColumnName+'=Source.'+@ColumnName+' And ';
set @QueryStatement+=('T.c.value(''(./'+@ColumnName+'[not(@xsi:nil)])[1]'','''+@DataType);--元素读取(包含空值情况)
if @MaxLength is not null and @MaxLength&&-1
set @QueryStatement+='('+CONVERT(nvarchar,@MaxLength)+')';
else if @MaxLength=-1 and @DataType&&'xml'
set @QueryStatement+='(max)';
set @QueryStatement+=(''') as '+@ColumnName+',');
fetch ColumnNameList Into @ColumnName,@DataType,@MaxLength
close ColumnNameL
Deallocate ColumnNameL
--去掉@FieldsList结尾的','
set @StrLength=LEN(@FieldsList);
set @FieldsList=SUBSTRING(@FieldsList,1,@StrLength-1);
--去掉@QueryStatement结尾的','
set @StrLength=LEN(@QueryStatement);
set @QueryStatement=SUBSTRING(@QueryStatement,1,@StrLength-1);
--去掉@Condition结尾的&and'
set @StrLength=LEN(rtrim(@Condition));
set @Condition=SUBSTRING(rtrim(@Condition),1,@StrLength-3);
set @Sql=N'USE DBT update '+@TableName+' set '+@FieldsList+' from (select '+@QueryStatement+'
from @DataSource.nodes(''/row'') as T(c)) Source where '+@C
else if @DMLType='D' --删除数据
--更新语句where后的条件表达式
declare @LinkField nvarchar(1000);
set @LinkField='
set @PKs=CONVERT(xml,dbo.uf_SplistString(@PrimaryKeyField,','));
open ColumnNameList
fetch ColumnNameList into @ColumnName,@DataType,@MaxL
while @@FETCH_STATUS=0
if @DataSource.exist('row/*[local-name()=sql:variable("@ColumnName")]')=1
set @IsPK=--初始化
--当前字段是否为主键
select @IsPK=Fs.F from (select T.c.value('.[text()]','nvarchar(128)') as F from @PKs.nodes('/Fields/Field') as T(c))Fs where Fs.F=@ColumnName
if @IsPK is not null and @IsPK&&''
--主键删除条件
set @LinkField+='Target.'+@ColumnName+'=Source.'+@ColumnName+' And ';
--XML 查询
set @QueryStatement+=('T.c.value(''(./'+@ColumnName+'[not(@xsi:nil)])[1]'','''+@DataType);--元素读取(包含空值情况)
if(@MaxLength is not null and @MaxLength&&-1)
set @QueryStatement+='('+CONVERT(nvarchar,@MaxLength)+')';
else if @MaxLength=-1 and @DataType&&'xml'
set @QueryStatement+='(max)';
set @QueryStatement+=(''') as '+@ColumnName+',');
fetch ColumnNameList into @ColumnName,@DataType,@MaxLength
close ColumnNameL
deallocate ColumnNameL
--去除@QueryStateMent结尾的','
set @StrLength=LEN(@QueryStatement);
set @QueryStatement=SUBSTRING(@QueryStatement,1,@StrLength-1);
--去除@LinkField 结尾的&Add&
set @StrLength=LEN(rtrim(@LinkField));
set @LinkField=SUBSTRING(rtrim(@LinkField),1,@StrLength-3);
set @Sql=N'Delete from '+@TableName+' from '+@TableName+' as Target inner join (select '+@QueryStatement+ ' from @DataSource.nodes(''/row'') as T(c)) Source on '+@LinkF
Return @Sql--'hello'
3.2.14 解析并处理从队列中读取的消息
这里主要用来读取队列中的消息,并将消息进行处理,最终处理成一定的格式,并调用3.2.13中的存储过程,将数据同步到数据库中。
--将数据同步到数据表中
create procedure UP_SyncDataToTable
set nocount on
--会话变量声明
declare @ConversationHan--会话句柄
declare @Msg_Body nvarchar(max);
declare @Msg_Type_N
declare @ErrorN
--变量赋值
while(1=1)
begin transaction
--从队列中接收消息
receive top(1)
@Msg_Type_Name=message_type_name,
@ConversationHandle=[conversation_handle],
@Msg_Body=message_body
from dbo.[DBTo_DataSyncQueue]
from dbo.[DBFrom_DataSyncQueue]
),timeout 500
--如果接收到消息-处理,否则跳过
if @@ROWCOUNT&=0
if @Msg_Type_Name='/Data/Sync'
--声明变量
declare @DMLType char(1);
declare @PrimaryKeyField nvarchar(128),@TableName nvarchar(128),@Sql nvarchar(4000);
declare @DataSource xml
--受影响的行数
declare @EffectRowC
declare @ErrM
--变量赋值
set @DataSource=convert(xml,@Msg_Body);--数据源
set @PrimaryKeyField=@DataSource.value('(/PrimaryKeyField)[1][text()]','nvarchar(128)');--主键列表
set @TableName=@DataSource.value('(/Table)[1][text()]','nvarchar(128)');--操作数据表
set @DMLType=@DataSource.value('/DMLType[1][text()]','char(1)');--操作类型
set @Sql=dbo.UF_XMLDataSourceToSQL(@DataSource,@TableName,@PrimaryKeyField,@DMLType);
exec sp_executesql @Sql,
N'@DataSource XML',
begin catch
declare @DBName nvarchar(128)
select @DBName=Name from master..SysDataBases where dbid=(select dbid from master..sysprocesses where spid=@@SPID)
set @ErrorNumber=ERROR_NUMBER();
set @ErrMsg=(select ERROR_NUMBER() as ErrNumber,
ERROR_SEVERITY() as ErrSeverity,
ERROR_STATE() as ErrState,
ERROR_PROCEDURE() as ErrProcedure,
ERROR_LINE() as ErrLine,
ERROR_MESSAGE() as ErrMessage,
@PrimaryKeyField as PrimaryKeyField,
@TableName as TableName,
@DMLType as DMLType,
@Msg_Body as MessageContent,
@DBName as DBName
for XML raw);
--GOTO 错误处理标签
goto Err_H
--结束会话
End Conversation @ConversationHandle
if @ErrorNumber is not null
--错误处理区域
Err_Handle:
if @ErrMsg is not null
declare @test nvarchar(128);
--发送失败消息
send on conversation @ConversationHandle
message type [/Data/Sync/Error](@ErrMsg)
--结束会话
end conversation @ConversationHandle
--回滚--不可回滚,否则将无法发送失败消息
commit transaction
3.2.15 对目标数据库的消息队列进行内部激活
这里主要是用来激活目标数据库的消息队列,主要用来实现数据的同步以及同步出错的错误信息的反馈。
--对Service Broker队列使用内部激活,并指定将要调用的存储过程
--alter Queue dbo.[DBTo_DataSyncQueue] with activation
alter Queue dbo.[DBFrom_DataSyncQueue] with activation
status=on,
max_queue_readers=1,
Procedure_name=UP_SyncDataToTable,
Execute as self
&&& 完成以上这些步骤以后,就可以实现同一数据库实例上两个不同的数据库之间的数据同步。即如果DBFrom数据库中的Org_Users中的某一条信息发生变化,会马上的自动同步到DBTo数据库中的Org_Users 表。如果是想要实现不同的数据库实例间的数据库的表的同步,则可以参考以下链接:
在创建启用传输安全、对话安全,创建路由、远程服务绑定等额外的操作之后,剩下的操作跟在同一数据库实例中的操作是一样的。
&&&&&& 此外,本文还参考了如下的链接:
&&&&&& 希望可以给大家一些启发和帮助。具体的源码有兴趣的朋友可以留下邮箱。

我要回帖

更多关于 超级跑跑网页同步版 的文章

 

随机推荐