共用方式為


SqlClient 疑難排解指南

下載 ADO.NET

連線到 SQL Server 時發生例外狀況

有許多原因會導致無法建立連線。 以下是一些疑難排解提示,可做為分析及解決許多問題的指南。

無法載入原生 SNI (伺服器網路介面) 程式庫

.NET Framework 應用程式中的問題

Stacktrace observed:

TypeInitializationException: The type initializer for 'Microsoft.Data.SqlClient.SNILoadHandle' threw an exception.
DllNotFoundException: Unable to load DLL 'Microsoft.Data.SqlClient.SNI.x64.dll': The specified module could not be found. (Exception from HRESULT: 0x8007007E)
TypeInitializationException: The type initializer for 'Microsoft.Data.SqlClient.SNILoadHandle' threw an exception.
DllNotFoundException: Unable to load DLL 'Microsoft.Data.SqlClient.SNI.x86.dll': The specified module could not be found. (Exception from HRESULT: 0x8007007E)

SNI 是 SqlClient 在 Windows 上執行時,於各種網路作業上皆須仰賴的原生 C++ 程式庫。 在使用 MSBuild 專案 SDK 建置的 .NET Framework 應用程式中,原生 DLL 不是以還原命令來管理。 .targets因此,NuGet 套件中包含Microsoft.Data.SqlClient.SNI可定義必要「複製」作業的檔案。

當直接相依至Microsoft.Data.SqlClient函式庫時,內含的.targets檔案會被自動參考。 在進行可轉移(間接)參考的案例中,應該手動參考此 .targets 檔案,以確保必要時可以執行「複製」作業。

建議的解決方案: 請確定 .targets 檔案是在應用程式的項目檔中參考,以確保執行「複製」作業。 在此<相關的 GitHub 問題>(英文) 中,可以找到專案檔的編輯範例。

這些目標僅會涵蓋 Microsoft 較知名且廣為使用的目標。 如果外部工具或應用程式定義自定義目標來複製二進位檔,則工具維護人員必須定義新的目標,以確保原生 SNI DLL 會與二進位檔一起 Microsoft.Data.SqlClient.dll 複製,而且在執行用戶端應用程式時可以使用。

.NET Core 應用程式中的問題

Stacktrace observed:

System.TypeInitializationException: The type initializer for 'Microsoft.Data.SqlClient.TdsParser' threw an exception.
---> System.TypeInitializationException: The type initializer for 'Microsoft.Data.SqlClient.SNILoadHandle' threw an exception.
---> System.DllNotFoundException: Unable to load shared library 'Microsoft.Data.SqlClient.SNI.dll' or one of its dependencies.

Note

此錯誤只會發生在 Windows 應用程式上。 如果其在 Unix 環境中發生,您必須確保應用程式已建置為能夠適當地以 Unix 執行階段為目標,而不是針對 Windows。

SNI 是 SqlClient 在 Windows 上執行時,於各種網路作業上皆須仰賴的原生 C++ 程式庫。 Microsoft.Data.SqlClient 不會在 .NET Core 中管理此程式庫的載入/解除載入。

建議的解決方案: 確定已在於 .NET Core 處理序中載入原生執行階段程式庫的檔案系統上授與「執行」權限。 如果那無法解決問題,您可以在 dotnet/runtime \(英文\) 存放庫中提出問題以取得進一步支援。

原生 SNI (找不到 pdb) 錯誤

Stacktrace observed:

An assembly specified in the application dependencies manifest (sql2csv.deps.json) was not found:
  package: 'Microsoft.Data.SqlClient.SNI.runtime', version: '2.0.0'
  path: 'runtimes/win-x64/native/Microsoft.Data.SqlClient.SNI.pdb'

建議的解決方案: 確定用戶端應用程式至少是參考 v2.1.0 \(英文\) 版的 Microsoft.Data.SqlClient 套件。 使用 EF Core 時,請直接將此套件版本的 Microsoft.Data.SqlClient 參考新增,以覆蓋相依性。

主機名稱解析錯誤

Stacktrace observed:

Microsoft.Data.SqlClient.SqlException (0x80131904): A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible.
Verify that the instance name is correct and that SQL Server is configured to allow remote connections.
(provider: TCP Provider, error: 0 - No such host is known.)
Microsoft.Data.SqlClient.SqlException (0x80131904): A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible.
Verify that the instance name is correct and that SQL Server is configured to allow remote connections.
(provider: TCP Provider, error: 35 - An internal exception was caught)
Microsoft.Data.SqlClient.SqlException (0x80131904): A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible.
Verify that the instance name is correct and that SQL Server is configured to allow remote connections.
(provider: TCP Provider, error: 35 - An internal exception was caught)
 ---> System.Net.Internals.SocketExceptionFactory+ExtendedSocketException (00000005, 0xFFFDFFFF): Name does not resolve

Possible reasons

  • 未在 SQL Server 上啟用 TCP/具名管道通訊協定

    建議的解決方案: 從 SQL Server 組態管理員主控台啟用 SQL Server 執行個體上的 TCP/具名管道通訊協定。

  • 未知的主機名稱

    建議的解決方案: 確定主機名稱能從起始連線的用戶端解析到伺服器的 IP 位址。

Login-phase errors

Stacktraces observed:

Microsoft.Data.SqlClient.SqlException (0x80131904): A connection was successfully established with the server, but then an error occurred during the pre-login handshake.
(provider: SSL Provider, error: 31 - Encryption(ssl/tls) handshake failed)
System.IO.EndOfStreamException: End of stream reached
A connection was successfully established with the server, but then an error occurred during the login process.
(provider: SSL Provider, error: 0 - The target principal name is incorrect.)
Microsoft.Data.SqlClient.SqlException (0x80131904): Connection Timeout Expired. The timeout period elapsed during the post-login phase. The connection could have timed out while waiting for server to complete the login process and respond; Or it could have timed out while attempting to create multiple active connections.
The duration spent while attempting to connect to this server was - [Pre-Login] initialization=837; handshake=394; [Login] initialization=3; authentication=15; [Post-Login] complete=1027;
---> System.ComponentModel.Win32Exception (258): Unknown error 258
at Microsoft.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action1 wrapCloseInAction)

可能的原因與解決方案

  • SQL Server 不支援 TLS 1.2

    此錯誤通常會在如 Docker 映像容器、Unix 用戶端或 Windows 用戶端等用戶端環境中發生,其中 TLS 1.2 是支援的最低 TLS 通訊協定。

    建議的解決方案: 在支援的 SQL Server 版本上安裝最新的更新,並確定伺服器上已啟用 TLS 1.2 通訊協定。

    Note

    請檢視 SqlClient 驅動程式支援生命週期,以取得支援的 SQL Server 不同版本清單,其中包含各版本的 Microsoft.Data.SqlClient

    不安全的解決方案: 在 Docker 映像/用戶端環境上設定 TLS/SSL 設定以使用 TLS 1.0 來連線。

    MinProtocol = TLSv1
    CipherString = DEFAULT@SECLEVEL=1
    

    Note

    從具有 TLS 1.0 或 TLS 1.1 的 Windows/Linux 環境連線 Microsoft.Data.SqlClient 到 v2.0+ 時,如果目標 SQL Server 和用戶端在建立連線時無法交涉至少 TLS 1.2 版,就會擲回安全性警告訊息:

    Security Warning: The negotiated <TLS1.0 | TLS1.1> is an insecure protocol and is supported for backward compatibility only. The recommended protocol version is TLS 1.2 and later.

  • SQL Server 強制加密

    若目標伺服器是已開啟 "Force Encryption" 屬性的 Azure SQL 執行個體或內部部署 SQL Server,則會建立加密連線,且用戶端必須與伺服器建立信任。

    建議的解決方案: 有兩個可用的選項可修正此問題:

    • 在客戶端環境中安裝目標 SQL Server 的 TLS 憑證。 如果需要加密,則系統會加以驗證。
    • (較不安全) 在連接字串中設定 "TrustServerCertificate=true" 屬性。

    不安全的解決方案: 在 SQL Server 上停用 [強制加密] 設定。

  • TLS 憑證未使用SHA-256或更新版本簽署。

    建議的解決方案: 為伺服器生成新的 TLS 憑證,並使用至少 SHA-256 雜湊演算法對其哈希進行簽署。

  • 使用 .NET 5+ 在 Linux 上嚴格限制的加密套件

    .NET 5 引進了 Linux 用戶端的重大變更,根據預設,其會使用嚴格限制的允許加密套件清單。 您可能需要展開預設加密套件清單,以接受舊版用戶端(或連絡舊版伺服器),方法是指定 CipherSuitePolicy 值或變更 OpenSSL 組態檔。

    如需建議的動作,請參閱 Linux 上 .NET 的預設 TLS 加密套件

    Microsoft.Data.SqlClient.SqlException (0x80131904): A connection was successfully established with the server, but then an error occurred during the login process. (provider: SSL Provider, error: 0 - The certificate chain was issued by an authority that is not trusted.)
    ---> System.ComponentModel.Win32Exception (0x80090325): The certificate chain was issued by an authority that is not trusted.
    
  • SQL Server 強制加密

    若目標伺服器是已開啟 "Force Encryption" 屬性的內部部署 SQL Server 以及自我簽署憑證,則會建立加密連線,且用戶端必須與伺服器建立信任。

    建議的解決方案: 有兩個可用的選項可修正此問題:

    • 在客戶端環境中安裝目標 SQL Server 的 TLS 憑證。 如果需要加密,則系統會加以驗證。
    • (較不安全) 在連接字串中設定 "TrustServerCertificate=true" 屬性。

    不安全的解決方案: 在 SQL Server 上停用 [強制加密] 設定。

連接集區耗盡錯誤

觀察到堆疊追蹤:

System.InvalidOperationException: Timeout expired. The timeout period elapsed prior to obtaining a connection from the pool.
This may have occurred because all pooled connections were in use and max pool size was reached.

可能的原因與解決方案

用戶端應用程式所開啟的連線數目,比起連接集區在任何時間點所能保持作用中的數目還要多。

建議的解決方案: 將 [集區大小上限] 連線屬性設定為較高的值,並及時關閉未使用的連線。

Contact Support

如果本指南無法解決連線問題,您可能會在 dotnet/sqlclient 存放庫中檢視現有的問題,並視需要開啟新的問題。