[高分求助]如何将数据从一台SQL服务器复制到另一台

时间:2022-04-30 04:45:42
我有A、B两台SQL服务器,
A服务器有数据库DB_a,其中有一表TB_a(id,name)
B服务器有数据库DB_b,其中有一表TB_b(id,stype,qty)

现在的问题是:TB_a中的记录是一直在增加的,怎样让TB_b与TB_a同步?
(同步的概念是:只要TB_a.id没有在TB_b中出现,那就复制TB_a中这条记录到TB_b。两个表的id字段都是主键)

请注意,这个问题的关键是,怎么去触发执行同步这一操作?
我现在用了个笨方法:用一段ASP代码,手工去点击它执行一下。
代码的形式算法描述如下:

建一个Connection连接数据库DB_a,
建一个Connection连接数据库DB_b,
建立记录集A(SELECT * FROM TB_a),
do while 记录集A没到尾部
  ID_a=记录集A.id
  建立记录集B(SELECT id FROM TB_b WHERE id=ID_a)
  IF 记录集B不为空 THEN
    INSERT INTO TB_b (id,) values(ID_a)
  END IF
loop
关闭Connection连接B
关闭Connection连接A


可以看出,上述这个过程其实效率是非常低的,我测试了一下,如果TB_a中有3000条记录的话,每点击执行一次这段代码需要20秒,这是不可以接受的。

网上看到有人说用存储过程来实现,但我对存储过程不是很熟练,不知道还有其他的办法没?
希望高手能指点一下。小弟不甚感激!

9 个解决方案

#1


等高手!

#2


邹老大的:
用触发器即时同步两个表的实例:   
    
  --测试环境:SQL2000,远程主机名:xz,用户名:sa,密码:无,数据库名:test   
    
  --创建测试表,不能用标识列做主键,因为不能进行正常更新   
  --在远程主机上建表   
  if   exists   (select   *   from   dbo.sysobjects   where   id   =   object_id(N'[test]')   and   OBJECTPROPERTY(id,   N'IsUserTable')   =   1)   
  drop   table   [test]   
    
  create   table   test(id   int   not   null   constraint   PK_test   primary   key   
  ,name   varchar(10))   
  go   
    
  --以下操作在本机进行   
  --在本机上建表及做同步处理的工作   
  if   exists   (select   *   from   dbo.sysobjects   where   id   =   object_id(N'[test]')   and   OBJECTPROPERTY(id,   N'IsUserTable')   =   1)   
  drop   table   [test]   
    
  create   table   test(id   int   identity(1,1)   primary   key   
  ,name   varchar(10))   
  go   
    
  --创建同步的触发器   
  create   trigger   t_test   on   test   
  for   insert,update,delete   
  as   
  set     XACT_ABORT   on   
  --启动远程服务器的MSDTC服务   
  exec   master..xp_cmdshell   'isql   /S"xz"   /U"sa"   /P""   /q"exec   master..xp_cmdshell   ''net   start   msdtc'',no_output"',no_output   
    
  --启动本机的MSDTC服务   
  exec   master..xp_cmdshell   'net   start   msdtc',no_output   
    
  --进行分布事务处理,如果表用标识列做主键,用下面的方法   
  BEGIN   DISTRIBUTED   TRANSACTION   
  delete   from   openrowset('sqloledb','xz';'sa';'',test.dbo.test)   
  where   id   in(select   id   from   deleted)   
  insert   into   openrowset('sqloledb','xz';'sa';'',test.dbo.test)   
  select   *   from   inserted   
  commit   tran   
  go   
    
  --插入数据测试   
  insert   into   test   
  select   1,'aa'   
  union   all   select   2,'bb'   
  union   all   select   3,'c'   
  union   all   select   4,'dd'   
  union   all   select   5,'ab'   
  union   all   select   6,'bc'   
  union   all   select   7,'ddd'   
    
  --删除数据测试   
  delete   from   test   where   id   in(1,4,6)   
    
  --更新数据测试   
  update   test   set   name=name+'_123'   where   id   in(3,5)   
    
  --显示测试的结果   
  select   *   from   test   a   full   join   
  openrowset('sqloledb','xz';'sa';'',test.dbo.test)   b   on   a.id=b.id   
  

#3


创建一个Command对象,定义其CommandText属性值为一个存储过程名。且将CommandType属性值设置为adCMdStoredProc,执行该Command对象的Execute方法便可完成存储过程的调用。再用Parameter对象实现存储过程的参数传递。

#4


dst导入

#5


多谢2楼!
但我的情况是,除了查询外,我不能对A服务器进行任何操作!

#6


直接夸库,做个job定时更新数据

#7


引用 6 楼 gingerkang 的回复:
直接夸库,做个job定时更新数据


呵呵,谢谢!不过,这个方法不是最好的!

定时更新如何实现?况且定时多久?1秒? 太频繁服务器吃不消,间隔太久,别人查询数据就不准确了!

#8


触发器 插入和更新和删除数据时 同步往b表进行插入和更新和删除操作。

#9


引用 7 楼 robinbest 的回复:
引用 6 楼 gingerkang 的回复:
直接夸库,做个job定时更新数据


呵呵,谢谢!不过,这个方法不是最好的!

定时更新如何实现?况且定时多久?1秒? 太频繁服务器吃不消,间隔太久,别人查询数据就不准确了!


你手动asp能准确吗?sqlserver带有作业可以定时,定多久都可以设置的,不然触发是最好的,但是你没操作权限说了不是跟没说一样.

#1


等高手!

#2


邹老大的:
用触发器即时同步两个表的实例:   
    
  --测试环境:SQL2000,远程主机名:xz,用户名:sa,密码:无,数据库名:test   
    
  --创建测试表,不能用标识列做主键,因为不能进行正常更新   
  --在远程主机上建表   
  if   exists   (select   *   from   dbo.sysobjects   where   id   =   object_id(N'[test]')   and   OBJECTPROPERTY(id,   N'IsUserTable')   =   1)   
  drop   table   [test]   
    
  create   table   test(id   int   not   null   constraint   PK_test   primary   key   
  ,name   varchar(10))   
  go   
    
  --以下操作在本机进行   
  --在本机上建表及做同步处理的工作   
  if   exists   (select   *   from   dbo.sysobjects   where   id   =   object_id(N'[test]')   and   OBJECTPROPERTY(id,   N'IsUserTable')   =   1)   
  drop   table   [test]   
    
  create   table   test(id   int   identity(1,1)   primary   key   
  ,name   varchar(10))   
  go   
    
  --创建同步的触发器   
  create   trigger   t_test   on   test   
  for   insert,update,delete   
  as   
  set     XACT_ABORT   on   
  --启动远程服务器的MSDTC服务   
  exec   master..xp_cmdshell   'isql   /S"xz"   /U"sa"   /P""   /q"exec   master..xp_cmdshell   ''net   start   msdtc'',no_output"',no_output   
    
  --启动本机的MSDTC服务   
  exec   master..xp_cmdshell   'net   start   msdtc',no_output   
    
  --进行分布事务处理,如果表用标识列做主键,用下面的方法   
  BEGIN   DISTRIBUTED   TRANSACTION   
  delete   from   openrowset('sqloledb','xz';'sa';'',test.dbo.test)   
  where   id   in(select   id   from   deleted)   
  insert   into   openrowset('sqloledb','xz';'sa';'',test.dbo.test)   
  select   *   from   inserted   
  commit   tran   
  go   
    
  --插入数据测试   
  insert   into   test   
  select   1,'aa'   
  union   all   select   2,'bb'   
  union   all   select   3,'c'   
  union   all   select   4,'dd'   
  union   all   select   5,'ab'   
  union   all   select   6,'bc'   
  union   all   select   7,'ddd'   
    
  --删除数据测试   
  delete   from   test   where   id   in(1,4,6)   
    
  --更新数据测试   
  update   test   set   name=name+'_123'   where   id   in(3,5)   
    
  --显示测试的结果   
  select   *   from   test   a   full   join   
  openrowset('sqloledb','xz';'sa';'',test.dbo.test)   b   on   a.id=b.id   
  

#3


创建一个Command对象,定义其CommandText属性值为一个存储过程名。且将CommandType属性值设置为adCMdStoredProc,执行该Command对象的Execute方法便可完成存储过程的调用。再用Parameter对象实现存储过程的参数传递。

#4


dst导入

#5


多谢2楼!
但我的情况是,除了查询外,我不能对A服务器进行任何操作!

#6


直接夸库,做个job定时更新数据

#7


引用 6 楼 gingerkang 的回复:
直接夸库,做个job定时更新数据


呵呵,谢谢!不过,这个方法不是最好的!

定时更新如何实现?况且定时多久?1秒? 太频繁服务器吃不消,间隔太久,别人查询数据就不准确了!

#8


触发器 插入和更新和删除数据时 同步往b表进行插入和更新和删除操作。

#9


引用 7 楼 robinbest 的回复:
引用 6 楼 gingerkang 的回复:
直接夸库,做个job定时更新数据


呵呵,谢谢!不过,这个方法不是最好的!

定时更新如何实现?况且定时多久?1秒? 太频繁服务器吃不消,间隔太久,别人查询数据就不准确了!


你手动asp能准确吗?sqlserver带有作业可以定时,定多久都可以设置的,不然触发是最好的,但是你没操作权限说了不是跟没说一样.