数据同步问题

lawbc 2010-04-14 09:23:06
目标表:sql类型的数据库表
源表:oracle类型的数据库表

前提:目标表与源表不一定是一一对应,即可能目标表对应了多个源表,反之也一样
目标表与源表可以直接进行通信,即提供查询字符串就可以执行sql

目的:由用户触发数据同步事件,从源表同步到目标表,而且同步是单步的,即不可以从目标表
同步到源表。

2个数据库表的字段可能不一样,这个要怎么搞呀
...全文
99 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
快乐_石头 2010-04-14
  • 打赏
  • 举报
回复
....
--小F-- 2010-04-14
  • 打赏
  • 举报
回复
说到同步,其实是靠"作业"定时调度存储过程来操作数据,增,删,改,全在里面,结合触发器,游标来实现,关于作业调度,我使用了5秒运行一次来实行"秒级作业",这样基本就算比较快的"同步"  


我做的是SQL Server往Oracle端同步,先在sql server上建立往Oracle端的链接服务器,我用一个视图"封装"了一下链接服务器下的一张表。


create view v_ora_PUBLISHLASTREC

as

select * from ORACLEDB..ROADSMS.PUBLISHLASTREC


//ORACLEDB链接服务器名,ROADSMS为表空间名,PUBLISHLASTREC 为数据表名


然后我们分别在sql server 要同步的表上建立,insert,delete,update触发器


脚本如下:


--说明:modiid等于1为insert,2为delete,3为update

create trigger trg_PUBLISHLASTREC_insert on PUBLISHLASTREC for insert

as

insert into dbo.PublishLastRec_SQL(modiid,SignalGUID,AreaNo,SignalNote,AreaNote,PublishRoadStatus,PublishTime,IsExec)

select '1',SignalGUID,AreaNo,SignalNote,AreaNote,PublishRoadStatus,PublishTime,'0' from inserted


create trigger trg_PUBLISHLASTREC_update on PUBLISHLASTREC for update

as

insert into dbo.PublishLastRec_SQL(modiid,SignalGUID,AreaNo,SignalNote,AreaNote,PublishRoadStatus,PublishTime,IsExec)

select '3',SignalGUID,AreaNo,SignalNote,AreaNote,PublishRoadStatus,PublishTime,'0' from inserted


create trigger trg_PUBLISHLASTREC_delete on PUBLISHLASTREC for delete

as

insert into dbo.PublishLastRec_SQL(modiid,SignalGUID,AreaNo,SignalNote,AreaNote,PublishRoadStatus,PublishTime,IsExec)

select '2',SignalGUID,AreaNo,SignalNote,AreaNote,PublishRoadStatus,PublishTime,'0' from deleted


所有的操作都是把各幻表的数据插入到一张表中,上面统一插入的表为PublishLastRec_SQL,记录下操作的标识,以标识该条记录是插入,删除,还是修改,modiid等于1为insert,2为delete,3为update,字段isexec标识该条记录是否已处理,0为未执行的,1为已执行的


接着就是最关键的一步,存储过程


脚本如下:


ALTER proc pro_PublishLastRec_Sql

as

declare @modiid int

declare @signalguid int

declare @areano numeric(1,0)

declare @signalnote varchar(50)

declare @areanote varchar(50)

declare @publishroadstatus varchar(20)

declare @publishtime varchar(50)


if not exists(select * from PublishLastRec_SQL where IsExec=0)

begin

truncate table PublishLastRec_SQL

return

end


declare cur_sql cursor for

select modiid,SignalGUID,AreaNo,SignalNote,AreaNote,PublishRoadStatus,PublishTime from

PublishLastRec_SQL where IsExec=0 order by [id]--IsExec 0为未执行的,1为已执行的

open cur_sql

fetch next from cur_sql into @modiid,@SignalGUID,@AreaNo,@SignalNote,@AreaNote,@PublishRoadStatus,@PublishTime


while @@fetch_status=0

begin

if (@modiid=1) --插入

begin

insert into v_ora_PUBLISHLASTREC(SignalGUID,AreaNo,SignalNote,AreaNote,PublishRoadStatus,PublishTime)

values(@SignalGUID,@AreaNo,@SignalNote,@AreaNote,@PublishRoadStatus,@PublishTime)

end

if (@modiid=2) --删除

begin

delete from v_ora_PUBLISHLASTREC where SignalGUID=@SignalGUID and AreaNo=@AreaNo

end

if (@modiid=3) --修改

begin

update v_ora_PUBLISHLASTREC

set SignalNote=@SignalNote,AreaNote=@AreaNote,PublishRoadStatus=@PublishRoadStatus,

PublishTime=@PublishTime

where SignalGUID=@SignalGUID and AreaNo=@AreaNo

end

update PublishLastRec_SQL

set IsExec=1

where current of cur_sql

fetch next from cur_sql into @modiid,@SignalGUID,@AreaNo,@SignalNote,@AreaNote,@PublishRoadStatus,@PublishTime

end

deallocate cur_sql


该存储过程使用游标逐行提取PublishLastRec_Sql记录,根据modiid判断不同的数据操作,该条记录处理完毕后把isexec字段更新为1.


最后是调用该存储过程的作业,我们先建一个一分钟运行一次的作业,然后在"步骤"的脚本中这样写:


DECLARE @dt datetime

SET @dt = DATEADD(minute, -1, GETDATE())

WHILE @dt < GETDATE()

BEGIN

EXEC pro_PublishLastRec_Sql --这里pro_PublishLastRec_Sql 为你要作业执行的存储过程

WAITFOR DELAY '00:00:05' -- 等待5秒, 根据你的需要设置即可

END

现在,我们即可以实现5秒执行一次该存储过程,做到5秒数据同步。
王向飞 2010-04-14
  • 打赏
  • 举报
回复
Q315054403 2010-04-14
  • 打赏
  • 举报
回复
写段代码定时执行。。。可针对某些表、字段处理,有偿支持
lawbc 2010-04-14
  • 打赏
  • 举报
回复
其实我这个需求不用触发器的,因为不要时时的,只要用户点击了同步按钮才区同步数据
而且会传入数据的id

问题是怎么去配置不同表间的关系
永生天地 2010-04-14
  • 打赏
  • 举报
回复
[Quote=引用楼主 liubiaocai 的回复:]
目标表:sql类型的数据库表
源表:oracle类型的数据库表

前提:目标表与源表不一定是一一对应,即可能目标表对应了多个源表,反之也一样
目标表与源表可以直接进行通信,即提供查询字符串就可以执行sql

目的:由用户触发数据同步事件,从源表同步到目标表,而且同步是单步的,即不可以从目标表
同步到源表。

2个数据库表的字段可能不一样,这个要怎么搞呀
[/Quote]
这个是比较麻烦的一件事。
最近我们准备用一家叫 XXX 的公司 的 tXXXXXr 的产品
正好研究了一阵,我把他的实现思想给你讲一下

他的产品用java开发,实现了异构异地数据同步(包括数据库)
数据库这里主要采取两种方式:
1、触发器方式:通过在每个表上建立insert update delete触发器来记录最新的数据
2、时间戳:在表上增加时间戳,记录最新的数据,删除必须用触发器

22,209

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server 疑难问题
社区管理员
  • 疑难问题社区
  • 尘觉
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧