SQL Server实时同步更新远程数据库遇到的问题小结

工作中遇到这样的情况,需要在更新表TableA(位于服务器ServerA 172.16.8.100中的库DatabaseA)同时更新TableB(位于服务器ServerB 172.16.8.101中的库DatabaseB)。

TableA与TableB结构相同,但数据数量不一定相同,应为有可能TableC也在更新TableB。由于数据更新不频繁,为简单起见想到使用了触发器Tirgger。记录一下遇到的一些问题:

1. 访问异地数据库

在ServerA 中创建指向ServerB的链接服务器,并做好账号映射。addlinkedserver存储过程创建一个链接服务器,参数详情参见官方文档。第1个参数LNK_ServerA是自定义的名称;第2参数产品名称,如果是SQL Server不用提供;第3个参数是驱动类型;第4个参数是数据源,这里写SQL Server服务器地址

exec sp_addlinkedserver 'LNK_ServerB_DatabaseB','','SQLNCLI','172.16.8.101'

配置链接服务器后,默认使用同一本地账号登陆远程数据库,如果账号有不同,还需要进行账号映射。sp_addlinkedsrvlogin参数详情参见官方文档。第1个参数同上;第2个参数false即使用后面参数提供的用户密码登陆;第3个参数null使所有本地账号都可以使用后面的用户密码来登陆链接服务器,如果第3个参数设置为一个本地SQL Server登陆用户名,那么只有这个用户才可以使用远程账号登陆链接服务器;最后两个是登录远程服务器的用户和密码。

exec sp_addlinkedsrvlogin 'LNK_ServerB_DatabaseB','false',null,'user','password'

如果要删除以上配置可以如下

exec sp_droplinkedsrvlogin 'LNK_ServerB_DatabaseB',null
exec sp_dropserver 'LNK_ServerB_DatabaseB','droplogins'

上面的配置在SQL Server Management Studio管理器里Server Objects下LinkedServers可以查询到,如果一切链接正常,可以直接打开链接服务器上的库表

值得注意的是以上两个存储过程不能出现在触发器代码中,而是事先在服务器ServerA中运行完成配置,否则触发器隐式事务的要求会报错“The procedure 'sys.sp_addlinkedserver' cannot be executed within a transaction.”

2. 配置分布式事务

SQL Server的触发器是隐式使用事务的,链接服务器是远程服务器,需要在本地服务器和远程服务器之间开启分布式事务处理,否则会报“The partner transaction manager has disabled its support for remote/network transactions”的错误。我在ServerA和ServerB中都开启分布式事务协调器,并进行适当配置,以支持分布式事务。ServerA和ServerB都是Windows Server 2012 R2,其他版本服务器类似。

(1)首先在Services.msc中确认Distributed Transaction Coordinator已经开启,其他版本的服务器不一定默认安装,需要安装windows features的方式先进行该特性的安装。

(2)在服务器管理工具Administrative Tools中找到Component Services,在Local DTC中属性Security选项卡中配置如下,打开相关安全设置,完成后会重启服务,也有文档称需要重启服务器,但是至少2012 R2不用。

(3)配置防火墙,Inbound和Outbound都打开

3. 数据库字段text, ntext的处理

业务中表TableA中有一个Content字段是text类型,同步到TableB时需要对内容做一些替换处理。对于text类型是一个过时的类型,微软官方建议用(N)VARCHAR(MAX)替换,可查阅这里。今后设计时可以考虑,这里我们考虑对text进行处理。

但是在触发器中,inserted和deleted表都是不允许对text/ntext/image类型进行处理的,这里我们采用一个曲线救国的办法,从数据库中把记录读取到临时表中,然后通过textptr和patindex函数和updatetext命令完成字符串替换处理

if exists(select * from tempdb..sysobjects where id=object_id('tempdb..#temp_tablea'))
 drop table #temp_tablea
select * into #temp_tablea from TableA where ID = @ID
declare @s varchar(200),@d varchar(200)
select @s='="/_target/',@d='="/_replacement/'
declare @p varbinary(16),@postion int,@l int
select @p=textptr(Content),@l=len(@s),@postion=patindex('%'+@s+'%',Content)+1 from #temp_tablea
while @postion>1
begin
 updatetext #temp_tablea.Content @p @postion @l @d
 select @postion=patindex('%'+@s+'%',Content)+1 from #temp_tablea
end

4. 执行远程数据库操作

当配置链接服务器时,我们可以直接访问远程数据库表了,如下

insert into LNK_ServerB_DatabaseB.DatabaseB.dbo.TableB ...
update LNK_ServerB_DatabaseB.DatabaseB.dbo.TableB set ...

但简陋的SQL编辑器往往会对语法报错,另外为方便编程,我们希望通过exec sp_executesql的方式获得更多的灵活性。其实exec就可以直接执行sql语句,但如果有返回值就比较困难了。如下,从远程服务器上通过ID查询表TableB后返回Name,sp_executesql存储过程可以使用output关键字定义变量为返回变量,其中@Name output为返回变量,@ID则是传入变量。

declare @sql nvarchar(500), @Name nvarchar(50),@ID nvarchar(40)
set @SQL=N'select @Name=Name from LNK_ServerB_DatabaseB.DatabaseB.dbo.TableB where ID=@ID'
exec sp_executesql @SQL,N'@Name nvarchar(50) output,@ID nvarchar(40)',@Name output,@ID

另外exec直接执行sql语句,本质上是执行拼接后的sql字符串,有时将变量拼接进字符串会困难的多(到底需要几个单引号),而sp_executesql则清晰多了

declare @SQL nvarchar(500),@Name nvarchar(50),@Count int,@ID nvarchar(40)
set @Name=N'Cat'
set @Count=0
set @ID=N'{00000000-0000-0000-0000-000000000000}'
set @SQL=N'update TableA set Name='''+@Name+''', Count='+@Count+' where ID='''+@ID+''''
exec(@SQL)
set @SQL=N'update TableA set Name=@Name,Count=@Count where ID=@ID'
exec sp_executesql @SQL, N'@Name nvarchar(50),@Count int,@ID nvarchar(40)',@Name,@Count,@ID

以上所述是小编给大家介绍的SQL Server实时同步更新远程数据库遇到的问题小结,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对我们网站的支持!

(0)

相关推荐

  • SQL server 2005将远程数据库导入到本地的方法

    远程数据库与本地数据库数据之间的导入导出,从来都是一个值得人关注的问题. 下面,就给你详细介绍SQL2005将远程数据库导入到本地的方法. 首先,将SQL2005打开.方法是:"开始"→"程序"→"Microsoft SQL Server 2005"→"SQL Server Management Studio",这样,就可以把本地的SQL2005打开了. 打开了本地的SQL2005之后,现在,如何把远程数据库中的数据库,导入到

  • SQLSERVER 本地查询更新操作远程数据库的代码

    复制代码 代码如下: --PK select * from sys.key_constraints where object_id = OBJECT_ID('TB') --FK select * from sys.foreign_keys where parent_object_id =OBJECT_ID('TB') --创建链接服务器 exec sp_addlinkedserver 'ITSV ', ' ', 'SQLOLEDB ', '远程服务器名或ip地址 ' exec sp_addlin

  • SQL Server 出现Error: 1326错误(管理器无法连接远程数据库)问题解决方案

    SQL Server 出现Error: 1326错误 我们在在使用SQL Server时都会遇到使用SQL Server Management Studio无法连接远程数据库实例的问题,错误描述信息摘录如下: An error has occurred while establishing a connection to the server. (provider: Named Pipes Provider, error: 40 – Could not open a connection to

  • SQL Server实时同步更新远程数据库遇到的问题小结

    工作中遇到这样的情况,需要在更新表TableA(位于服务器ServerA 172.16.8.100中的库DatabaseA)同时更新TableB(位于服务器ServerB 172.16.8.101中的库DatabaseB). TableA与TableB结构相同,但数据数量不一定相同,应为有可能TableC也在更新TableB.由于数据更新不频繁,为简单起见想到使用了触发器Tirgger.记录一下遇到的一些问题: 1. 访问异地数据库 在ServerA 中创建指向ServerB的链接服务器,并做好

  • SQL Server 2005 同步复制技术

    一.准备工作: 1.建立一个 WINDOWS 用户,设置为管理员权限,并设置密码,作为发布快照文件的有效访问用户. 2.在SQL SERVER下实现发布服务器和订阅服务器的通信正常(即可以互访).打开1433端口,在防火墙中设特例 3.在发布服务器上建立一个共享目录,作为发布快照文件的存放目录.例如:在D盘根目录下建文件夹名为SqlCopy 4.设置SQL 代理(发布服务器和订阅服务器均设置) 打开服务(控制面板---管理工具---服务) ---右击SQLSERVER AGENT---属性---

  • 你真的了解触发器么 数据实时同步更新问题剖析

    当我们想更新一张动态表的时候(即:表中的数据不断的添加),也许我们会用数据库代理,通过写作业,然后让他定时查询动态表中最新添加的数据,然后更新数据.这样时能实现更新数据的要求,但是数据却不能实时同步更新. 这个时候,触发器就是我们想要的神器了.我们可以在那张动态表上新建触发器.触发器的实质就是个存储过程,只不过他调用的时间是根据所建的动态表发生该表而执行(即:Insert新数据,Update或者Delete数据). 具体怎么使用触发器,今天我这里就不介绍了,园子里资料多的很.那么我今天要介绍的是

  • 配置 SQL Server 2005 以允许远程连接的方法

    例如,在使用 SQLCMD 实用工具连接到 SQL Server 时收到以下错误消息: 复制代码 代码如下: Sqlcmd:错误:Microsoft SQL Native Client:建立到服务器的连接时发生错误.连接到 SQL Server 2005 时,默认设置 SQL Server 不允许远程连接这个事实可能会导致失败. 如果没有将 SQL Server 2005 配置为接受远程连接,则可能会发生此问题.默认情况下,SQL Server 2005 Express Edition 和 SQ

  • sql server实现在多个数据库间快速查询某个表信息的方法

    本文实例讲述了sql server实现在多个数据库间快速查询某个表信息的方法.分享给大家供大家参考,具体如下: 最近出来实习,所在公司的服务器有十几个数据库,为了方便根据某个数据表的  表名  快速找到对应的数据库,又复习了一下游标的知识,写了下面这个sql代码,方便自己的工作. 1.先了解一下系统存储过程和系统表的使用,简单介绍一下我用到的几个系统存储过程(资料参考网络) use master --切换到系统数据库,因为下面用到的系统存储过程和系统表大部分存在于该数据库 go exec sp_

  • SQL Server 2005“备份集中的数据库备份与现有的数据库不同”解决方法

    以前一直使用SQL Server2000,现在跟潮流都这么紧,而且制定要求使用SQL Server2005,就在现在的项目中使用它了.  对于SQL Server 2005,有几个地方是要注意的,比方在还原数据库时,不像2000里边将数据库和文件区分的很细,统一均为文件,这就使还原的数据库文件制定为. bak.那么想还原2000的数据库(备份数据库文件,无后缀名的),就需要自己手工选择. 选择下拉框中的"所有文件",这时就会显示"备份数据库文件"了,选择-确定 最主

  • 比较SQL Server与Oracle、DB2数据库的一些知识

    开放性 SQL Server 只能在Windows 上运行,没有丝毫的开放性,操作系统的系统的稳定对数据库是十分重要的.Windows9X系列产品是偏重于桌面应用,NT server只适合中小型企业.而且Windows平台的可靠性,安全性和伸缩性是非常有限的.它不象Unix那样久经考验,尤其是在处理大数据量的关键业务时. Oracle 能在所有主流平台上运行(包括 Windows).完全支持所有的工业标准.采用完全开放策略.可以使客户选择最适合的解决方案.对开发商全力支持. DB2 能在所有主流

  • sql server 2012 备份集中的数据库备份与现有的xxx数据库不同

    SQL Server 2005备份的数据库还原到SQL Server 2012失败,错误信息如下: 解决方法 由于是还原完整数据库备份,因此删除SQL Server 2012同名数据库再还原,还原成功:

  • SQL Server 2005删除日志文件的几种方法小结

    使用MS数据库的朋友就会知道一个问题,C盘的空间很容易被占满了.因为本来系统盘就分区比较小,这是由于数据库在使用过程中会使日志文件不断增加,使得数据库的性能下降,并且占用大量的磁盘空间.SQL Server数据库都有log文件,log文件记录用户对数据库修改的操作.可以通过直接删除log文件和清空日志在清除数据库日志. 一.删除LOG1.分离数据库.分离数据库之前一定要做好数据库的全备份,选择数据库--右键--任务--分离. 勾选删除连接 分离后在数据库列表将看不到已分离的数据库. 2.删除LO

  • sql server 复制表从一个数据库到另一个数据库

    /*不同服务器数据库之间的数据操作*/ --创建链接服务器 exec sp_addlinkedserver 'ITSV ', ' ', 'SQLOLEDB ', '远程服务器名或ip地址 ' exec sp_addlinkedsrvlogin 'ITSV ', 'false ',null, '用户名 ', '密码 ' --查询示例 select * from ITSV.数据库名.dbo.表名 --导入示例 select * into 表 from ITSV.数据库名.dbo.表名 --以后不再使

随机推荐