ADO (ActiveX Data Objects) 是微軟建立在 OLE DB 之上的高層數據訪問接口,比 ODBC API、DAO、RDO 更簡單易用且不失靈活性。本文以 Access 數據庫為例,演示 VC++ 下 ADO 核心操作流程。
AfxOleInit())#import 指令)Connection 對象並連接數據庫Recordset 進行數據操作// StdAfx.h
#import "C:\Program Files\Common Files\System\ADO\msado15.dll" no_namespace rename("EOF", "adoEOF")
// App.cpp
BOOL CMyApp::InitInstance()
{
AfxOleInit(); // 必須調用
// ...
}
注意:
msado15.dll路徑需按實際環境調整;編譯時可能出現C4146警告,微軟建議忽略。
_ConnectionPtr m_pConnection;
HRESULT hr;
try {
hr = m_pConnection.CreateInstance("ADODB.Connection");
if (SUCCEEDED(hr)) {
// Access 2000+ 連接字符串
hr = m_pConnection->Open("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=test.mdb", "", "", adModeUnknown);
// Access 97 請用 Provider=Microsoft.Jet.OLEDB.3.51
// SQL Server 直連:driver={SQL Server};Server=127.0.0.1;DATABASE=db;UID=sa;PWD=xxx
}
}
catch (_com_error &e) {
CString msg; msg.Format(_T("連接失敗: %s"), e.ErrorMessage());
AfxMessageBox(msg);
}
三種常用方式:
// 方式 1: Connection::Execute
_variant_t rowsAffected;
m_pConnection->Execute("CREATE TABLE users(ID INT, name TEXT, age INT, birthday DATETIME)", &rowsAffected, adCmdText);
m_pConnection->Execute("INSERT INTO users VALUES(1, 'Washington', 25, '1970/1/1')", &rowsAffected, adCmdText);
_RecordsetPtr rs = m_pConnection->Execute("SELECT COUNT(*) FROM users", &rowsAffected, adCmdText);
long count = rs->GetCollect((long)0); rs->Close();
// 方式 3: Recordset::Open (靜態游標、樂觀鎖,支持更新)
_RecordsetPtr m_pRecordset;
m_pRecordset.CreateInstance("ADODB.Recordset");
m_pRecordset->Open("SELECT * FROM users", _variant_t((IDispatch*)m_pConnection, true), adOpenStatic, adLockOptimistic, adCmdText);
_variant_t vID, vName, vAge, vBirthday;
while (!m_pRecordset->adoEOF) {
vID = m_pRecordset->GetCollect((long)0);
vName = m_pRecordset->GetCollect("name");
vAge = m_pRecordset->GetCollect("age");
vBirthday = m_pRecordset->GetCollect("birthday");
TRACE(_T("ID:%d, 姓名:%s, 年齡:%d, 生日:%s\n"), vID.lVal, (LPCTSTR)(_bstr_t)vName, vAge.lVal, (LPCTSTR)(_bstr_t)vBirthday);
m_pRecordset->MoveNext();
}
m_pRecordset->MoveFirst();
m_pRecordset->Delete(adAffectCurrent); // 刪除首行
for (int i=0; i<3; i++) {
m_pRecordset->AddNew();
m_pRecordset->PutCollect("ID", i+10);
m_pRecordset->PutCollect("name", _T("葉利欽"));
m_pRecordset->PutCollect("age", 71);
m_pRecordset->PutCollect("birthday", _T("1930-3-15"));
}
m_pRecordset->Move(1, _variant_t((long)adBookmarkFirst)); // 移至第 2 行
m_pRecordset->PutCollect("age", 45);
m_pRecordset->Update();
if (m_pRecordset) m_pRecordset->Close();
if (m_pConnection) m_pConnection->Close();
BeginTrans/CommitTrans/RollbackTrans)