問題
最近朋友一個系統環境 DB 是 SQL Server 2008 R2 (192.168.211.213),AP Server 改使用 Windows 2022。
分別裝了 2 台 AP Server (192.168.211.204 及 192.168.211.205),卻發現其中有一台(192.168.211.204)連線時會發生 SQL Server does not exist or access denied 的錯誤,另一台則是正常的。
ERROR [08001] [Microsoft][ODBC SQL Server Driver][DBNETLIB]SQL Server 不存在或拒絕存取。
ERROR [01000] [Microsoft][ODBC SQL Server Driver][DBNETLIB]ConnectionOpen (Connect()).
ERROR [01S00] [Microsoft][ODBC SQL Server Driver]無效的連線字串屬性
調查及解決
它的連線字串為,driver={SQL Server};Server=192.168.211.213;port=62667;Database=RMDB;uid=rm;pwd=rmpwd
使用 OdbcConnection,程式如下,
設定檔內容,
1 | <appSettings> |
1 | OdbcConnection conn = new OdbcConnection(); |
因為 ODBC 除了有 SQL Server 這個 Driver ,還有 ODBC Driver 17 for SQL Server ,
所以就將連線字串改成,driver={ODBC Driver 17 for SQL Server};Server=192.168.211.213;port=62667;Database=RMDB;uid=rm;pwd=rmpwd
結果就發生 具名管理提供者: 無法開啟 SQL Server 連線 的錯誤,如下,
ERROR [08001] [Microsoft][ODBC Driver 17 for SQL Server]具名管理提供者: 無法開啟 SQL Server 連線 [5]
ERROR [01S00] [Microsoft][ODBC Driver 17 for SQL Server]無效的連線字串屬性
奇怪,怎麼不是走 TCP/IP ,而是走 Named Pipes 呢?
透過Microsoft Network Monitor 3.4在 DB Server 錄到的封包,192.168.211.204 => 192.168.211.213
192.168.211.205 => 192.168.211.213
可以發現,用同樣的連線字串,AP(204)連 DB 是走1433 Port, 而 AP(205)卻是走正確的62667
仔細看一下連線字串好像怪怪的,參考SqlConnection.Open 方法的說明,
如果您嘗試連線到 SQL Server 的實例,並使用 TCP/IP 以外的通訊協定時,指定 1433 以外的埠號碼,此方法就會 Open 失敗。 若要指定 1433 以外的埠號碼,請在連接字串中包含 「server=machinename,port number」,並使用 TCP/IP 通訊協定
目前的連線字串是driver={SQL Server};Server=192.168.211.213;port=62667;Database=RMDB;uid=rm;pwd=rmpwd,
應該是要改成driver={SQL Server};Server=192.168.211.213,62667;Database=RMDB;uid=rm;pwd=rmpwd,
才是正確的。
所以將設定內容中的<add key="DB2_HOSTNAME" value="192.168.211.213">
改成<add key="DB2_HOSTNAME" value="192.168.211.213,62667"> AP-204 就可以正常連線了。
但為什麼 AP-205 連線字串的 HOST 並沒有加,port number,卻可以連線成功呢?
於是想到 SQL Server 組態管理員 可以設定 Client 的通訊協定及別名,
但是 AP 打開來,裡面的確有設定192.168.211.213別名,同時設定它走 62667 Port。
卻只有32位元的 Client 設定,並沒有64位元的 Client 設定
但因為程式是 X64 的,所以直接看機碼比較快,64位元的機碼如下,電腦\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSSQLServer\Client\ConnectTo
32位元的機碼如下,電腦\HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\MSSQLServer\Client\ConnectTo
結果一看 AP-205 有一個192.168.211.213別名,並設定走 TCP 62667 Port。
而 AP-204 別名卻是192.168.211.213,62667,並設定走 TCP 62667 Port。
原來是別名設定錯誤,難怪 AP-204 會用 TCP 1433 去連。
請朋友將機碼的名稱從192.168.211.213,62667 改成 192.168.211.213 就沒問題了。
結論
以上雖然只是幾步,但查花了幾天的時間才找出這些問題。
如果有詳細去看錯誤訊息無效的連線字串屬性,應該可以及早發現是連線字串的問題。
如果可以早點到機碼檢查 SQL Client 別名,應該也可以早點確認是SQL Server 組態管理員設定別名的問題。
原來SQL Server 組態管理員的SQL Native Client 11.0 組態會影響到ODBC的 SQL 連線。
為什麼那個連線字串為什麼 Port 寫在連線字串的屬性中(port=62667)呢?
從設定中的名稱就可以發現原本使用的 DB 應該是IBM DB2,後來才改成SQL Server的。
因為 IBM DB2 的 ODBC 連線字串就是Driver={IBM DB2 ODBC DRIVER};Database=myDataBase;Hostname=myServerAddress;Port=1234;Protocol=TCPIP;Uid=myUsername;Pwd=myPassword;
參考資源
Microsoft Network Monitor 3.4
SqlConnection.Open 方法
一床被,蓋不出兩樣人: 有其父必有其子,是好是壞,差不了多少。