
資料庫:Demo.mdb,資料表:DemoTable,欄位:Name (Text)、Age (Integer)。
// 1. Stdafx.h 引入類型庫
#import "c:\\program files\\common files\\system\\ado\\msado15.dll" \
no_namespace rename("EOF", "adoEOF")
// 2. COM 初始化 (擇一)
// 方案 A: MFC 自動管理
AfxOleInit(); // 僅呼叫一次,自動在結束時 CoUninitialize
// 方案 B: 手動控制
CoInitialize(NULL); // 初始
// ... 程式結束 ...
CoUninitialize(); // 釋放
// 3. 編譯產生 .tlh/.tli,智慧指標自動管理參考計數
| 指標 | 用途 | 關鍵方法 |
|---|---|---|
| _ConnectionPtr | 連線管理 | Open, Close, Execute, BeginTrans, CommitTrans, RollbackTrans, OpenSchema |
| _RecordsetPtr | 資料游標 | Open, Close, MoveFirst/Next/Previous/Last, AddNew, Update, Delete, GetCollect, PutCollect, GetFields, Fields, adoEOF, BOF |
| _CommandPtr | 參數化指令/預存程序 | ActiveConnection, CommandText, Execute, Parameters, CreateParameter |
_ConnectionPtr m_pConnection;
AfxOleInit();
m_pConnection.CreateInstance(__uuidof(Connection));
try {
m_pConnection->Open(_T("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=Demo.mdb"),
_T(""), _T(""), adModeUnknown);
} catch (_com_error e) {
AfxMessageBox(_T("連線失敗,確認 Demo.mdb 是否在當前路徑!"));
return FALSE;
}
// 關閉
if (m_pConnection->State) m_pConnection->Close();
m_pConnection = NULL;
_RecordsetPtr m_pRecordset;
m_pRecordset.CreateInstance(__uuidof(Recordset));
try {
m_pRecordset->Open(_T("SELECT * FROM DemoTable"),
theApp.m_pConnection.GetInterfacePtr(), // 取得 IDispatch*
adOpenDynamic, adLockOptimistic, adCmdText);
} catch (_com_error* e) {
AfxMessageBox(e->ErrorMessage());
}
_variant_t var; CString strName, strAge;
try {
if (!m_pRecordset->BOF) m_pRecordset->MoveFirst();
else { AfxMessageBox(_T("表內無資料")); return; }
while (!m_pRecordset->adoEOF) {
var = m_pRecordset->GetCollect(_T("Name"));
if (var.vt != VT_NULL) strName = (LPCSTR)_bstr_t(var);
var = m_pRecordset->GetCollect(_T("Age"));
if (var.vt != VT_NULL) strAge = (LPCSTR)_bstr_t(var);
m_AccessList.AddString(strName + _T(" --> ") + strAge);
m_pRecordset->MoveNext();
}
m_AccessList.SetCurSel(0);
} catch (_com_error* e) { AfxMessageBox(e->ErrorMessage()); }
try {
m_pRecordset->AddNew();
m_pRecordset->PutCollect(_T("Name"), _variant_t(m_Name));
m_pRecordset->PutCollect(_T("Age"), _variant_t(_ttoi(m_Age)));
m_pRecordset->Update();
AfxMessageBox(_T("新增成功!"));
} catch (_com_error* e) { AfxMessageBox(e->ErrorMessage()); }
// 相對移動
m_pRecordset->MoveFirst();
m_pRecordset->Move(long(curSel)); // curSel 為 ListBox 選取索引 (0-based)
// 絕對定位 (需支援書籤的游標)
m_pRecordset->MoveFirst();
m_pRecordset->Move(3, adBookmarkFirst); // 從第一筆起跳 3 筆
try {
m_pRecordset->MoveFirst(); m_pRecordset->Move(1); // 定位第 2 筆 (0-based)
m_pRecordset->PutCollect(_T("Name"), _variant_t(m_Name));
m_pRecordset->PutCollect(_T("Age"), _variant_t(_ttoi(m_Age)));
m_pRecordset->Update();
} catch (_com_error* e) { AfxMessageBox(e->ErrorMessage()); }
try {
m_pRecordset->MoveFirst(); m_pRecordset->Move(1);
m_pRecordset->Delete(adAffectCurrent); // 僅刪除目前記錄
m_pRecordset->Update();
} catch (_com_error* e) { AfxMessageBox(e->ErrorMessage()); }
m_pRecordset->Close(); m_pRecordset = NULL;
// 執行 SQL
_CommandPtr m_pCommand;
m_pCommand.CreateInstance(__uuidof(Command));
m_pCommand->ActiveConnection = m_pConnection;
m_pCommand->CommandText = _T("SELECT * FROM DemoTable");
m_pRecordset = m_pCommand->Execute(NULL, NULL, adCmdText);
// 執行預存程序 (Access 稱 Query)
m_pCommand->CommandText = _T("DemoQuery");
m_pCommand->Execute(NULL, NULL, adCmdStoredProc);
// 參數化查詢範例 (需 _ParameterPtr)
_ParameterPtr pParam = m_pCommand->CreateParameter(_T("@Age"), adInteger, adParamInput, 4, 25);
m_pCommand->Parameters->Append(pParam);
m_pCommand->CommandText = _T("SELECT * FROM DemoTable WHERE Age > @Age");
m_pRecordset = m_pCommand->Execute(NULL, NULL, adCmdText);
m_pConnection->Errors 集合取得詳細資訊Release(),但明確設為 NULL 更安全