翻譯至“sqlwithmanoj”的博客
http://sqlwithmanoj.wordpress.com/tag/sqlncli10/
小伙伴們震驚了吧,“SQL Server 2012” 不支持通過連接服務器的方式連接到“SQL Server 2000”了。SQL Server 2012 采用了新版本的SQLNCL11(SQL Server Native Client 11)替代了以前的SQLNCL10,這個客戶端只支持連接到2008R2,2008,2005版本的數據庫。
筆者加一句:這個SQLNCL11不僅不能通過分布查詢連接2000版本數據庫,還原操作也不能進行,簡而言之,不能讀取2000版本的數據了。
問題是這樣復現的:
- 我將我的數據庫升級從 2008R2 升級到了2012
- 將從2008R2 服務器備份的數據庫文件還原到了 2012服務器上
- 在新服務器上執行任務時候,出現了這樣的錯誤
錯誤信息:
OLE DB provider “SQLNCLI11″ for linked server “NorthWind2000″ returned message “Client unable to establish connection”.
Msg 22, Level 16, State 1, Line 0
SQL Server Native Client 11.0 does not support connections to SQL Server 2000 or earlier versions.
OLE DB provider “SQLNCLI11″ for linked server “NorthWind2000″ returned message “Invalid connection string attribute”.
由於我是升級了數據庫,所以我把問題定位到了連接服務器的OLE DB(對象鏈接嵌入數據庫)應用程序接口上,發現了這個SQLNCL11的版本,同時我的服務器上還有SQLNCL10版本。
所以我試着顯示使用SQLNCL10去創建連接服務器,但還是出現了如下異常:
Msg 8522, Level 16, State 3, Line 1
Microsoft Distributed Transaction Coordinator (MS DTC) has stopped this transaction.
我貼出我創建連接服務器的腳本,如下:
USE [master] GO -- Existing LinkedServer [NorthWind2000]: EXEC master.dbo.sp_addlinkedserver @server = N'NorthWind2000', @srvproduct=N'MSSQL', @provider=N'SQLNCLI', @provstr=N'PROVIDER=SQLOLEDB;SERVER=NorthWind' EXEC master.dbo.sp_addlinkedsrvlogin @rmtsrvname=N'NorthWind2000',@useself=N'True',@locallogin=NULL,@rmtuser=NULL,@rmtpassword=NULL GO
--->以下是替代的解決方案:
使用ODBC是一個比較好的方案,有兩種實現方式
- 在操作系統中穿件一個ODBC Data Source (DSN),在SQLSERVER中只用這個DSN創建連接服務器。
- 創建連接服務器時候,直接使用DSN的連接字符串調用ODBC接口。
第一種方式:
首先創建ODBC數據源
- 打開控制面板,進入管理工具,選擇”數據源(ODBC)“
- 在”ODBC數據源管理器“頁簽,選取”系統DSN“面板
- 單擊添加創建一個新的數據源
- 選擇”SQL Server“然后點擊完成
筆者多嘴2:基本上各大數據庫甚至excel都提供了相關接口,都可以連接
- 在新建數據源頁面,建議給數據源適當的命名(比如: NorthWind2000DSN),這個命名會在以后創建練級服務器時候使用到,這里就叫NorthWind,點擊下一步
- 選擇驗證方式,Windows驗證或者Sqlserver都無所謂,進入下一步
- 選擇默認數據庫,不選也無所謂,下一步
- 點擊完成,新的DSN就創建了
現在可以使用DSN創建連接服務器了,在@dadasrc參數中使用DSN名稱,同時@provider參數中要填寫”MSDASQL“.
以下是示例SQL
-- Drop Existing LinkedServer [NorthWind2000]: EXEC master.dbo.sp_dropserver @server=N'NorthWind2000', @droplogins='droplogins' GO -- Re-create LinkedServer [NorthWind2000] by using the ODBC connection: EXEC master.dbo.sp_addlinkedserver @server = N'NorthWind2000', @srvproduct=N'MSDASQL', @provider=N'MSDASQL', @datasrc = N'NorthWind2000DSN', @location=N'System'; EXEC master.dbo.sp_addlinkedsrvlogin @rmtsrvname=N'NorthWind2000',@useself=N'True',@locallogin=NULL,@rmtuser=NULL,@rmtpassword=NULL GO
第二種方式:
直接使用DSN字符串也挺好,在@provstr參數中直接使用DSN連接字符串,請看:
-- Drop Existing LinkedServer [NorthWind2000]: EXEC master.dbo.sp_dropserver @server=N'NorthWind2000', @droplogins='droplogins' GO -- Re-create LinkedServer [NorthWind2000] by using the ODBC connection: EXEC master.dbo.sp_addlinkedserver @server = N'NorthWind2000', @srvproduct=N'', @provider=N'MSDASQL', @provstr=N'DRIVER={SQL Server};SERVER=NorthWind;Trusted_Connection=yes;' EXEC master.dbo.sp_addlinkedsrvlogin @rmtsrvname=N'NorthWind2000',@useself=N'True',@locallogin=NULL,@rmtuser=NULL,@rmtpassword=NULL GO
使用這種方式可以實現在2012服務器上分布式查詢2000版本數據庫的數據。
這種方式看似可以直接替代以前的連接服務器,其實效率降低了,如果想實現更有效率的ETL操作,建議升級源數據庫的版本,至少到SQL2005。
筆者多嘴3:據不完全統計,ODBC數據源查詢效率約為使用SQLNCL查詢的1/4。