ADO (ActiveX Data Objects) 是微軟提供的高階資料存取介面,建立在 OLE DB 之上,支援關聯式資料庫、Excel、文字檔、郵件系統等多樣資料源。本文涵蓋 VC++ 專案導入 ADO、COM 初始化、三大核心介面(_ConnectionPtr、_CommandPtr、_RecordsetPtr)用法與常見操作模式。
// StdAfx.h
#import "C:\\Program Files\\Common Files\\System\\ado\\msado15.dll" \
no_namespace rename("EOF", "adoEOF")
no_namespace:避免需寫 ADODB:: 前綴。rename("EOF", "adoEOF"):避免與標準巨集 EOF 衝突。
// CMyApp::InitInstance
if (!AfxOleInit()) { // 或 CoInitialize(NULL)
AfxMessageBox(_T("OLE/COM 初始化失敗"));
return FALSE;
}
| 介面 | 主要用途 | 典型方法 |
|---|---|---|
_ConnectionPtr | 管理資料庫連線、執行無傳回結果的 SQL (DDL、存儲過程) | Open, Execute, Close, BeginTrans/CommitTrans/RollbackTrans |
_CommandPtr | 參數化命令、預存程序、可重複執行的 SQL | Execute, CreateParameter, Parameters->Append |
_RecordsetPtr | 查詢結果集、游標操作、資料繫結 | Open, MoveNext/Previous/First/Last, GetCollect, Update/AddNew/Delete, Filter/Sort |
// SQL Server (OLE DB Provider)
_bstr_t connStr = "Provider=SQLOLEDB;Data Source=127.0.0.1;Initial Catalog=MyDB;User ID=sa;Password=123;";
// Access (Jet OLEDB)
_bstr_t connStr = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\\Data.mdb;";
// ODBC DSN
_bstr_t connStr = "DSN=MyOdbcDsn;UID=user;PWD=pass;";
_ConnectionPtr pConn(__uuidof(Connection));
_RecordsetPtr pRs(__uuidof(Recordset));
pConn->Open(connStr, "", "", adConnectUnspecified);
pRs->Open("SELECT * FROM Users WHERE Age > ?", _variant_t((IDispatch*)pConn),
adOpenStatic, adLockReadOnly, adCmdText);
// 參數化查詢 (需用 Command)
_CommandPtr pCmd(__uuidof(Command));
pCmd->ActiveConnection = pConn;
pCmd->CommandText = "SELECT * FROM Users WHERE Age > ?";
pCmd->CommandType = adCmdText;
pCmd->Parameters->Append(pCmd->CreateParameter(_T("Age"), adInteger, adParamInput, 4, 25));
pRs = pCmd->Execute(NULL, NULL, adCmdText);
while (!pRs->adoEOF) {
_variant_t vName = pRs->GetCollect(_T("Name"));
_variant_t vAge = pRs->GetCollect(_T("Age"));
CString name = (LPCTSTR)(_bstr_t)vName;
int age = (int)vAge;
TRACE(_T("User: %s, Age: %d\n"), name, age);
pRs->MoveNext();
}
pRs->Close();
pConn->Close();
// 新增
pRs->Open("Users", _variant_t((IDispatch*)pConn), adOpenKeyset, adLockOptimistic, adCmdTable);
pRs->AddNew();
pRs->PutCollect(_T("Name"), _T("NewUser"));
pRs->PutCollect(_T("Age"), 30);
pRs->Update();
// 修改
pRs->Filter = _T("Name='NewUser'");
if (!pRs->adoEOF) {
pRs->PutCollect(_T("Age"), 31);
pRs->Update();
}
// 刪除
pRs->Filter = _T("Name='NewUser'");
if (!pRs->adoEOF) pRs->Delete();
try {
// ADO 操作...
}
catch (_com_error& e) {
CString msg;
msg.Format(_T("ADO 錯誤: %s (0x%08X)"), e.ErrorMessage(), e.Error());
AfxMessageBox(msg);
}
adOpenForwardOnly + adLockReadOnly 最快,僅支援單向讀取。GetRows 一次取回二維陣列,避免逐筆 MoveNext 開銷。Release,但長生命週期物件建議顯式 Close。