2011-09-03 95 views
1

最近,我們的QA團隊在我們的一個應用程序中報告了一個非常有趣的錯誤。我們的應用程序是一個基於C#.Net 3.5 SP1的應用程序,與SQL Server 2005 Express Edition數據庫進行交互。SQL Server:無法找到帶有句柄的準備語句x

通過設計中的應用開發,以檢測數據庫脫機的情況,如果是等到數據庫聯機(由重試及時進行連接),一旦上線,重新連接和恢復功能。

什麼我們的QA團隊所做的是,在該應用從數據庫中檢索的大量數據,停止數據庫服務器,等待一段時間,然後重新啓動數據庫。一旦數據庫重新啓動,應用程序將重新連接到數據庫而沒有任何問題,但它開始不斷地報告異常「無法找到帶有句柄x的預處理語句」(x是某個數字)。

我們的應用程序使用預處理語句,它是專門設計,再次調用prepare()方法對所有的SqlCommand對象時,應用程序重新連接到數據庫。例如,

在應用啓動時,

SqlCommand _commandA = connection.CreateCommand(); 
    _commandA.CommandText = @"SELECT COMPANYNAME FROM TBCOMPANY WHERE ID = @ID"; 
    _commandA.CommandType = CommandType.Text; 
    SqlParameter _paramA = _commandA.CreateParameter(); 
    _paramA.ParameterName = "@ID"; 
    _paramA.SqlDbType = SqlDbType.Int; 
    _paramA.Direction = ParameterDirection.Input; 
    _paramA.Size = 0; 
    _commandA.Parameters.Add(_paramA); 
    _commandA.Prepare(); 

之後,我們在本申請的每個週期使用在此_commandA ExceuteReader()具有不同@ID參數值。

一旦應用程序檢測到數據庫脫機並重新聯機,在重新連接到數據庫的應用程序只執行,

_commandA.Prepare(); 

兩個更奇怪的事情,我們注意到。 1.上述情況發生在代碼中的CommandType.Text類型命令中。我們的應用程序也使用相同的確切邏輯來調用存儲過程,但我們從來沒有在存儲過程中遇到過這個問題。 2.到目前爲止,無論我們在Visual Studio的Debug模式下嘗試多少種不同的方式,都無法重現此問題。

在此先感謝..

回答

1

我覺得差不多有3天的時間提出這個問題,並且接近20個觀點的問題和1個答案,我不得不得出結論,這不是我們可以用我們用SQL服務器嘗試的方式處理的情況。

在你的應用程序,以減輕這一問題的最好辦法是,一旦應用程序檢測到數據庫聯機再次重新創建SqlCommand對象實例。

我們確實在我們的應用程序的變化,我們的QA團隊很高興這個修改,因爲它提供了最好的(也許是唯一)解決他們報告的問題。

最後感謝大家誰查看和回答了這個問題。

0

服務器緩存,當你調用「command.Prepare」的查詢計劃。該錯誤表示在您再次調用「Prepare」時無法找到此緩存的查詢計劃。嘗試創建一個新的'SqlCommand'實例並在其上調用查詢。我以前遇到過這個異常,當服務器刷新緩存時它會自行修復。我懷疑有什麼可以在客戶端以編程方式完成,以解決這個問題。

+0

感謝您的回覆。我還懷疑是否有任何事情可以解決這個問題,而不是在重新連接數據庫時重新創建SqlCommand實例。我們已經嘗試過這一點,它當然在起作用。但是,我們在基於Oracle 11g R2數據庫的中央數據中心應用程序中嘗試了這一點,在數據庫關閉並重新啓動後,這種僅調用Prepare()的邏輯沒有任何問題。這就是爲什麼我們想知道爲什麼它不適用於SQL Server。也許'Oracle + ODAC'比'SQL server + SqlClient'更聰明...... :) –

+0

這是一個Sql Server特定的錯誤。它不會在Oracle數據庫上發生。 – alwayslearning

0

這沒有必然的關係究竟你的問題,但我張貼這是我花了幾天想在我的應用程序來解決同樣的錯誤消息。我們有一個Java應用程序使用C3P0連接池,JTDS驅動程序,連接到SQL Server數據庫。

我們在C3P0連接池中禁用了語句緩存,但是在驅動程序級別上沒有這樣做。向我們的連接URL添加maxStatements = 0停止了驅動程序緩存語句,並修復了錯誤。