成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

SQL Server實時同步更新遠程數據庫遇到的問題

數據庫 SQL Server
TableA與TableB結構相同,但數據數量不一定相同,應為有可能TableC也在更新TableB。由于數據更新不頻繁,為簡單起見想到使用了觸發器Tirgger。

工作中遇到這樣的情況,需要在更新表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服務器地址

  1. exec sp_addlinkedserver 'LNK_ServerB_DatabaseB','','SQLNCLI','172.16.8.101' 

配置鏈接服務器后,默認使用同一本地賬號登陸遠程數據庫,如果賬號有不同,還需要進行賬號映射。sp_addlinkedsrvlogin參數詳情參見官方文檔。第1個參數同上;第2個參數false即使用后面參數提供的用戶密碼登陸;第3個參數null使所有本地賬號都可以使用后面的用戶密碼來登陸鏈接服務器,如果第3個參數設置為一個本地SQL Server登陸用戶名,那么只有這個用戶才可以使用遠程賬號登陸鏈接服務器;***兩個是登錄遠程服務器的用戶和密碼。

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

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

  1. exec sp_droplinkedsrvlogin 'LNK_ServerB_DatabaseB',null 
  2. 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字段是ntext類型,同步到TableB時需要對內容做一些替換處理。對于text和ntext類型是一個過時的類型,微軟官方建議用(N)VARCHAR(MAX)替換,可查閱這里。今后設計時可以考慮,這里我們考慮對ntext進行處理。

但是在觸發器中,inserted和deleted表都是不允許對text/ntext/image類型進行處理的,這里我們采用一個曲線救國的辦法,從數據庫中把記錄讀取到臨時表中,然后通過textptr和patindex函數和updatetext命令完成字符串替換處理

  1. if exists(select * from tempdb..sysobjects where id=object_id('tempdb..#temp_tablea'))  
  2.     drop table #temp_tablea 
  3. select * into #temp_tablea from TableA where ID = @ID 
  4. declare @s varchar(200),@d varchar(200) 
  5. select @s='/_target/',@d='/_replacement/' 
  6. declare @p varbinary(16),@postion int,@l int 
  7. select @p=textptr(Content),@l=len(@s),@postion=patindex('%'+@s+'%',Content)-1 from #temp_tablea 
  8. while @postion>0 
  9. begin 
  10.     updatetext #temp_tablea.Content @p @postion @l @d 
  11.     select @postion=patindex('%'+@s+'%',Content)-1 from #temp_tablea 

 

特別注意以上代碼對于text類型處理中文時會出問題,由于text存儲non-unicode的數據,patindex會將中文字符解釋為1個字符,而updatetext命令卻將中文字符解釋為2個字符。SQL Server 2005以上版本可以這樣做替換:

  1. update #temp_tablea set Content=cast(replace(cast(Content as nvarchar(max)),@s,@d) as text) 

4. 執行遠程數據庫操作

當配置鏈接服務器時,我們可以直接訪問遠程數據庫表了,如下

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

但簡陋的SQL編輯器往往會對語法報錯,另外為方便編程,我們希望通過exec sp_executesql的方式獲得更多的靈活性。其實exec就可以直接執行sql語句,但如果有返回值就比較困難了。如下,從遠程服務器上通過ID查詢表TableB后返回Name,sp_executesql存儲過程可以使用output關鍵字定義變量為返回變量,其中@Name output為返回變量,@ID則是傳入變量。

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

另外exec直接執行sql語句,本質上是執行拼接后的sql字符串,有時將變量拼接進字符串會困難的多(到底需要幾個單引號),而sp_executesql則清晰多了

  1. declare @SQL nvarchar(500),@Name nvarchar(50),@Count int,@ID nvarchar(40) 
  2. set @Name=N'Cat' 
  3. set @Count=0 
  4. set @ID=N'{00000000-0000-0000-0000-000000000000}' 
  5. set @SQL=N'update TableA set Name='''+@Name+''', Count='+@Count+' where ID='''+@ID+'''' 
  6. exec(@SQL) 
  7. set @SQL=N'update TableA set Name=@Name,Count=@Count where ID=@ID' 
  8. exec sp_executesql @SQL, N'@Name nvarchar(50),@Count int,@ID nvarchar(40)',@Name,@Count,@ID 
責任編輯:武曉燕 來源: 博客園
相關推薦

2024-10-30 08:15:18

2010-07-01 15:44:22

SQL Server數

2010-05-24 18:05:12

MySQL數據庫

2009-11-18 16:16:51

Oracle數據庫

2010-08-27 09:59:51

SQL Server

2010-07-22 11:17:52

SQL Server數

2011-09-07 15:11:31

SQL Server同步

2010-07-15 17:28:50

SQL Server

2009-05-26 10:21:07

2011-07-13 16:19:54

存儲過程SQL Server數

2011-08-15 16:58:34

SQL Server遠程查詢批量導入數據

2011-04-06 16:15:21

SQL Server數簡體繁體

2011-01-19 09:51:25

SQL Server

2010-07-08 11:05:14

SQL Server數

2010-07-06 14:40:15

解決SQL Serve

2019-10-08 15:54:42

SQL數據庫技術

2011-03-24 09:07:11

SQL Server數備份

2011-03-24 09:24:08

SQL Server數還原

2011-03-24 09:45:34

SQL Server數恢復

2020-09-21 11:30:28

CanalMySQL數據庫
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 精品日本久久久久久久久久 | 精品综合久久 | 亚洲激情在线观看 | 97伦理| 亚洲欧洲视频 | 91精品国产综合久久小仙女图片 | 三级免费av | 色在线免费视频 | 日韩精品视频在线 | 亚洲国产高清在线 | 在线免费av电影 | 超碰在线97国产 | 国产999精品久久久久久 | 日韩理论电影在线观看 | 久久中文字幕视频 | 亚洲国产免费 | 国产精品高潮呻吟久久av黑人 | 日韩中文一区 | 欧美三级在线 | 欧美一区二区三 | 91社影院在线观看 | 黄色成人免费看 | 国产日产欧产精品精品推荐蛮挑 | 韩国av网站在线观看 | av一区二区在线观看 | 日本一区二区不卡视频 | www.99精品| 亚洲欧美中文日韩在线v日本 | 国产高清免费 | 中文字幕高清 | 久久午夜视频 | 久久99国产精品 | 依人成人 | 99re视频这里只有精品 | 中文字幕在线看第二 | 狠狠综合久久av一区二区小说 | 国产视频第一页 | 日本一区二区三区精品视频 | 国产精品一区二区不卡 | 91原创视频 | 日韩一区二区不卡 |