| 订阅 | 在线投稿
分享
 
 
 

经验总结:SQL Server与Oracle的数据同步

来源:互联网网民  宽屏版  评论
2008-06-13 06:49:09

这篇论坛文章(赛迪网技术社区)主要介绍了SQL Server与Oracle的数据同步方案及解决过程,更多内容请参考下文:

说到同步,其实是靠"作业"定时调度存储过程来操作数据,增,删,改,全在里面,结合触发器,游标来实现,关于作业调度,我使用了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秒数据同步。

 
特别声明:以上内容(如有图片或视频亦包括在内)为网络用户发布,本站仅提供信息存储服务。
 
这篇论坛文章(赛迪网技术社区)主要介绍了SQL Server与Oracle的数据同步方案及解决过程,更多内容请参考下文: 说到同步,其实是靠"作业"定时调度存储过程来操作数据,增,删,改,全在里面,结合触发器,游标来实现,关于作业调度,我使用了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秒数据同步。
󰈣󰈤
 
 
 
>>返回首页<<
 
 热帖排行
 
 
 
静静地坐在废墟上,四周的荒凉一望无际,忽然觉得,凄凉也很美
©2005- 王朝网络 版权所有