首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

ADO 操作 Access 資料庫:重複使用 ADO 物件導致 IDispatch error #3092 之解決方案

     編輯:程式設計綜合問答

問題現象

在 MFC 應用程式中封裝 CADO 類別操作 Access 資料庫,建構函數初始化 COM 與連線,解構函數釋放資源。提供 ExecuteSQL 方法回傳 _RecordsetPtr。當在列表控制項點擊欄位排序時,首次執行正常,第二次即拋出 IDispatch error #3092 (0x800A0E78)。

根本原因

ExecuteSQL 每次呼叫都會建立新的 _RecordsetPtr 並回傳,但在 AddToList 中使用該記錄集遍歷後,並未顯式釋放該記錄集物件。再次點擊排序時,前一個記錄集仍處於開啟狀態,導致連線或游標衝突,引發未知錯誤。

解決方法

  1. 在 AddToList 結束前釋放記錄集
    遍歷完成後,呼叫 m_pRecordset->Close() 並將智慧指標設為 NULL(或讓其離開作用域自動釋放)。
  2. 修正 ExecuteSQL 回傳方式
    建議改為傳入參數接收記錄集,避免臨時物件生命週期管理混淆:
    void ExecuteSQL(CString sql, _RecordsetPtr& rs);
  3. 確保連線物件唯一且正確管理
    CADO 建構/解構函數中對 m_pConnection 的 CreateInstance/Release 配對正確,但需注意多執行緒環境下的同步問題。

關鍵代碼調整

void CTeacherDlg::AddToList(CString bstrSQL) {
    try {
        m_pRecordset = m_ado.ExecuteSQL(bstrSQL);
        while (!m_pRecordset->adoEOF) {
            // ... 填充列表 ...
            m_pRecordset->MoveNext();
        }
        // 新增:顯式關閉並釋放
        if (m_pRecordset) {
            m_pRecordset->Close();
            m_pRecordset.Release();
        }
    } catch (_com_error &e) {
        // 錯誤處理
    }
}

最佳實踐總結

  • ADO 智慧指標(_ConnectionPtr, _RecordsetPtr)雖自動管理參考計數,但跨函數回傳時仍需明確所有權歸屬。
  • 資料庫操作函數建議採用「傳入輸出參數」模式,由呼叫端負責物件生命週期。
  • 錯誤 0x800A0E78 通常指向游標或鎖定衝突,優先檢查前一個 Recordset 是否已正確關閉。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved