如何避免在 .NET 應用程序中從 SQL Server 返回部分數據?
我們從客戶端獲得票證,該票證有時會從查詢中獲取部分數據。簡單的單詞查詢是視圖查詢:
SELECT column1, column2, column3, column4, column5, column6 ... column50 from [dbo].[view]
查看返回大約 300 萬條記錄。在伺服器上,我們有一些規則會在執行 30 分鐘後終止查詢。在正常情況下,此查詢執行大約 5 分鐘,但在工作量大的情況下,此查詢執行超過 30 分鐘。在這種情況下,客戶端可能會遇到兩種錯誤:
• 返回的終止查詢
“消息 596,級別 21 無法繼續執行,因為會話處於終止狀態”
這會導致應用程序導入節點失敗,因此是“理想”情況,因為它們不依賴於具有部分輸入數據集的工作流。
• 一個與殺死程序相關的場景
“消息 0,級別 20 目前命令發生嚴重錯誤”
從 ODBC 的角度來看,這看起來與成功執行相同,因此我們以部分數據集結束 - 這是最危險的情況。
你知道如何避免這種問題嗎?
您遺漏了第二個錯誤中最重要的部分(強調我的):
目前命令發生嚴重錯誤。 結果,如果有的話,應該丟棄。
無論“應用程序導入節點”是什麼,它都需要通過丟棄結果集來處理此錯誤 - 並可能撤消它對迄今為止已流式傳輸的結果所做的任何工作。
任何其他解決方案都將是一種解決方法,並且可能是不安全的解決方案。
重要的是要注意,雖然
KILL
spid 會導致此錯誤,但從磁碟讀取損壞的頁面也是如此。如果您意外看到此錯誤,您應該執行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 驅動程序進行了嘗試,但都遇到了錯誤:
我得到的錯誤如下:
用於 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
和以前一樣
綜上所述,應用程序應該在被終止的連接上出現錯誤。它應該具有處理查詢被終止時結果可能尚未完成的事實的邏輯。