目标表:sql类型的数据库表
源表:oracle类型的数据库表前提:目标表与源表不一定是一一对应,即可能目标表对应了多个源表,反之也一样
      目标表与源表可以直接进行通信,即提供查询字符串就可以执行sql目的:由用户触发数据同步事件,从源表同步到目标表,而且同步是单步的,即不可以从目标表
      同步到源表。2个数据库表的字段可能不一样,这个要怎么搞呀

解决方案 »

  1.   

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

  2.   

    这个是比较麻烦的一件事。
    最近我们准备用一家叫 XXX 的公司 的 tXXXXXr 的产品
    正好研究了一阵,我把他的实现思想给你讲一下他的产品用java开发,实现了异构异地数据同步(包括数据库)
    数据库这里主要采取两种方式:
    1、触发器方式:通过在每个表上建立insert update delete触发器来记录最新的数据
    2、时间戳:在表上增加时间戳,记录最新的数据,删除必须用触发器