• SQLServer与Oracle的数据同步(触发器trigger)


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

  • 相关阅读:
    数位dp
    可持久化Trie
    网络流
    欧拉定理
    点、边双,圆方树
    [USACO5.3]窗体面积Window Area
    6.2三道模拟
    BZOJ2054 疯狂的馒头
    [USACO5.1]夜空繁星Starry Night
    [USACO5.1]乐曲主题Musical Themes
  • 原文地址:https://www.cnblogs.com/quanweiru/p/4905853.html
Copyright © 2020-2023  润新知