Sql-Server

如何避免在 .NET 應用程序中從 SQL Server 返回部分數據?

  • February 9, 2022

我們從客戶端獲得票證,該票證有時會從查詢中獲取部分數據。簡單的單詞查詢是視圖查詢:

SELECT column1, column2, column3, column4, column5, column6 ... column50 
from [dbo].[view]

查看返回大約 300 萬條記錄。在伺服器上,我們有一些規則會在執行 30 分鐘後終止查詢。在正常情況下,此查詢執行大約 5 分鐘,但在工作量大的情況下,此查詢執行超過 30 分鐘。在這種情況下,客戶端可能會遇到兩種錯誤:

• 返回的終止查詢

“消息 596,級別 21 無法繼續執行,因為會話處於終止狀態”

這會導致應用程序導入節點失敗,因此是“理想”情況,因為它們不依賴於具有部分輸入數據集的工作流。

• 一個與殺死程序相關的場景

“消息 0,級別 20 目前命令發生嚴重錯誤”

從 ODBC 的角度來看,這看起來與成功執行相同,因此我們以部分數據集結束 - 這是最危險的情況。

你知道如何避免這種問題嗎?

您遺漏了第二個錯誤中最重要的部分(強調我的):

目前命令發生嚴重錯誤。 結果,如果有的話,應該丟棄。

無論“應用程序導入節點”是什麼,它都需要通過丟棄結果集來處理此錯誤 - 並可能撤消它對迄今為止已流式傳輸的結果所做的任何工作。

任何其他解決方案都將是一種解決方法,並且可能是不安全的解決方案。

重要的是要注意,雖然KILLspid 會導致此錯誤,但從磁碟讀取損壞的頁面也是如此。如果您意外看到此錯誤,您應該執行DBCC CHECKDB以確保您的數據是安全的。

…您確定通過 ODBC 的連接可以擷取這種錯誤嗎?

我用 C# 編寫了一個小程序,它創建一個 ODBC 連接(使用System.Data.OdbcConnection該類)並從一個長時間執行的查詢中開始流式傳輸結果:

using System.Data.Odbc;

try
{
   var connection = new OdbcConnection("DSN=SQL2019");
   var command = new OdbcCommand(@"SELECT * FROM dbo.Posts", connection);

   connection.Open();
   var reader = command.ExecuteReader();

   while (reader.Read())
   {
       var id = reader.GetInt32(reader.GetOrdinal("Id"));
       Console.WriteLine(id);
   }
}
catch (Exception e)
{
   Console.WriteLine(e);
   throw;
}

每次我執行程序時,我都會等待幾秒鐘,然後KILL在執行我的查詢的 spid 上發出一個命令。

我在我的電腦上使用四種不同的 ODBC 驅動程序進行了嘗試,但都遇到了錯誤:

用於此測試的 ODBC 驅動程序的螢幕截圖

我得到的錯誤如下:


用於 SQL Server 的 ODBC 驅動程序 17

System.Data.Odbc.OdbcException (0x80131937):錯誤

$$ 08S01 $$ $$ Microsoft $$$$ ODBC Driver 17 for SQL Server $$TCP Provider:遠端主機強行關閉了現有連接。 錯誤

$$ 08S01 $$ $$ Microsoft $$$$ ODBC Driver 17 for SQL Server $$通訊鏈路故障

SQL 伺服器

System.InvalidOperationException:連接已被禁用。

—> System.Data.Odbc.OdbcException (0x80131937): 錯誤

$$ 01000 $$ $$ Microsoft $$$$ ODBC SQL Server Driver $$$$ DBMSLPCN $$連接讀取 (recv())。

錯誤$$ 08S01 $$ $$ Microsoft $$$$ ODBC SQL Server Driver $$$$ DBMSLPCN $$一般網路錯誤。檢查您的網路文件。

SQL Server 本地客戶端 11.0

System.Data.Odbc.OdbcException (0x80131937):錯誤

$$ 08S01 $$ $$ Microsoft $$$$ SQL Server Native Client 11.0 $$TCP Provider:遠端主機強行關閉了現有連接。 錯誤

$$ 08S01 $$ $$ Microsoft $$$$ SQL Server Native Client 11.0 $$通訊鏈路故障

SQL Server 本機客戶端 RDA 11.0

和以前一樣


綜上所述,應用程序應該在被終止的連接上出現錯誤。它應該具有處理查詢被終止時結果可能尚未完成的事實的邏輯。

引用自:https://dba.stackexchange.com/questions/307155