存儲過程不返回記錄集導致ADO程序出錯
HRESULT _hr = get_adoEOF(&_result);
IsEOF()函數如下:其中ADOCG::_RecordsetPtr m_pRecordset;
BOOL IsEOF() {return m_pRecordset->adoEOF == VARIANT_TRUE;};
m_pRecordset->adoEOF 將執行下面的函數(見msado15。tli)
1 inline VARIANT_BOOL Recordset15::GetadoEOF ( ) {
2 VARIANT_BOOL _result = 0;
3 HRESULT _hr = get_adoEOF(&_result);
4 if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this));
5 return _result;
6 }
程序將在上述第三行代碼處拋出異常。
經過查詢網上的資料以及和同事一起研究發現。在存儲過程中沒有返回記錄集的路徑中增加一個SELECT TOP 0 0 創造一個空記錄集返回也可避免該異常的發生。所以,存儲過程中沒有返回記錄集是導致該問題的根本原因。
還有一種避免(僅僅是避免)該異常的方法是在執行完存儲過程後,先使用如下代碼來判斷記錄集是否已經打開
if (m_pRecordset->GetState() == ADOCG::adStateClosed)
return FALSE;
else
return TRUE;
如果記錄集未打開,則直接通知上傳調用模塊不要再做記錄集操作。
最後小結下該問題的處理方法。
1.程序調用存儲過程時,是否返回記錄集時由存儲過程本身決定的。一般的我們首先使用SET NOCOUNT ON 來關閉計數,防止幹擾我們通過SELECT語句返回我們期望的記錄集。
2.從存儲過程本身下手。保證設計為返回記錄集的存儲過程,必須在任何時候都有查詢語句返回記錄集。即使查詢條件不符合也要返回一個空記錄集。以保證存儲過程的健壯性。
3.修改ADO封裝類的函數:BOOL CADORecordset::Open(LPCTSTR lpstrExec)
在執行存儲過程並返回記錄集後,先檢查記錄集是否打開。如果未打開,則返回FALSE,通知上層程序,打開記錄集出錯。 應該進行相應的錯誤處理而不是繼續操作記錄集。
存儲過程不返回記錄集導致ADO程序出錯的分析 - nscboy的專欄 - CSDN博客 http://blog.csdn.net/nscboy/article/details/4168777
存儲過程不返回記錄集導致ADO程序出錯