在 MFC 應用程式中封裝 CADO 類別操作 Access 資料庫,建構函數初始化 COM 與連線,解構函數釋放資源。提供 ExecuteSQL 方法回傳 _RecordsetPtr。當在列表控制項點擊欄位排序時,首次執行正常,第二次即拋出 IDispatch error #3092 (0x800A0E78)。
ExecuteSQL 每次呼叫都會建立新的 _RecordsetPtr 並回傳,但在 AddToList 中使用該記錄集遍歷後,並未顯式釋放該記錄集物件。再次點擊排序時,前一個記錄集仍處於開啟狀態,導致連線或游標衝突,引發未知錯誤。
AddToList 結束前釋放記錄集m_pRecordset->Close() 並將智慧指標設為 NULL(或讓其離開作用域自動釋放)。ExecuteSQL 回傳方式void ExecuteSQL(CString sql, _RecordsetPtr& rs);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) {
// 錯誤處理
}
}
_ConnectionPtr, _RecordsetPtr)雖自動管理參考計數,但跨函數回傳時仍需明確所有權歸屬。0x800A0E78 通常指向游標或鎖定衝突,優先檢查前一個 Recordset 是否已正確關閉。