下面的文章主要介绍的是SQL Server数据库和Oracle数据库的数据同步方案以及具体的解决过程,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的数据同步方案及解决过程的介绍,望你能有所收获。
【编辑推荐】