| |
【赛迪网-it技术报道】这篇论坛文章(赛迪网技术社区)主要介绍了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秒数据同步。
|
|