ADO 建構於 OLE DB 之上,比 ODBC API、DAO、RDO 更簡單易用且不失彈性。本文詳細說明 VC++ 下 ADO 開發基本流程與程式碼範例,採用 Access 資料庫供測試。
BOOL CADOTestApp::InitInstance()
{
AfxOleInit(); // 初始化 COM
// ...
}
// stdafx.h
#import "C:\\Program Files\\Common Files\\System\\ADO\\msado15.dll" \
no_namespace rename("EOF", "adoEOF")
編譯時可能出現 warning C4146,微軟建議忽略。
_ConnectionPtr m_pConnection;
BOOL CADOTestDlg::OnInitDialog()
{
CDialog::OnInitDialog();
HRESULT hr;
try
{
hr = m_pConnection.CreateInstance(__uuidof(Connection));
if (SUCCEEDED(hr))
{
// Access 2000
hr = m_pConnection->Open(
_T("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=test.mdb"),
_T(""), _T(""), adModeUnknown);
// Access 97 需改用 Provider=Microsoft.Jet.OLEDB.3.51
}
}
catch (_com_error e)
{
CString msg;
msg.Format(_T("連接失敗!\r\n%s"), e.ErrorMessage());
AfxMessageBox(msg);
}
return TRUE;
}
Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\\test.mdbData Source=adotest;UID=sa;PWD=;driver={SQL Server};Server=127.0.0.1;DATABASE=db;UID=sa;PWD=123ConnectionTimeout:設定逾時秒數,須在 Open 前呼叫State:0=關閉、1=開啟,可用於判斷是否需關閉定義 _RecordsetPtr m_pRecordset; 並 CreateInstance。
_variant_t vtAffected;
m_pConnection->Execute(_T("CREATE TABLE users(ID INT, username TEXT, old INT, birthday DATETIME)"),
&vtAffected, adCmdText);
m_pConnection->Execute(_T("INSERT INTO users VALUES(1, 'Washington', 25, '1970/1/1')"),
&vtAffected, adCmdText);
m_pConnection->Execute(_T("UPDATE users SET old = old+1"), &vtAffected, adCmdText);
m_pRecordset = m_pConnection->Execute(_T("SELECT COUNT(*) FROM users"), &vtAffected, adCmdText);
_variant_t vtCount = m_pRecordset->GetCollect((long)0);
m_pRecordset->Close();
AfxMessageBox(_T("記錄數: ") + CString((char*)_bstr_t(vtCount)));
_CommandPtr pCmd;
pCmd.CreateInstance(__uuidof(Command));
_variant_t vNull; vNull.vt = VT_ERROR; vNull.scode = DISP_E_PARAMNOTFOUND;
pCmd->ActiveConnection = m_pConnection;
pCmd->CommandText = _T("SELECT * FROM users");
m_pRecordset = pCmd->Execute(&vNull, &vNull, adCmdText);
m_pRecordset->Open(
_T("SELECT * FROM users"),
_variant_t((IDispatch*)m_pConnection, true),
adOpenStatic, adLockOptimistic, adCmdText);
游標類型:adOpenForwardOnly(唯向前)、adOpenKeyset、adOpenDynamic(動態)、adOpenStatic(靜態快照)。
鎖定類型:adLockReadOnly、adLockPessimistic(悲觀)、adLockOptimistic(樂觀)、adLockBatchOptimistic(批次樂觀)。
m_pRecordset->Open(_T("SELECT * FROM users"), ...);
while (!m_pRecordset->adoEOF)
{
_variant_t vId = m_pRecordset->GetCollect(_T("ID"));
_variant_t vName = m_pRecordset->GetCollect(_T("username"));
// ... 處理資料
m_pRecordset->MoveNext();
}
// 新增記錄
for (int i = 0; i < 3; i++)
{
m_pRecordset->AddNew();
m_pRecordset->PutCollect(_T("ID"), _variant_t(i + 10));
m_pRecordset->PutCollect(_T("username"), _variant_t(_T("葉利欽")));
m_pRecordset->PutCollect(_T("old"), _variant_t(71));
m_pRecordset->PutCollect(_T("birthday"), _variant_t(_T("1930-3-15")));
}
// 移至第 2 筆並修改
m_pRecordset->Move(1, _variant_t(adBookmarkFirst));
m_pRecordset->PutCollect(_T("old"), _variant_t(45));
m_pRecordset->Update();
m_pRecordset->Close();
m_pConnection->Close();
下一篇將介紹 Recordset 進階屬性/方法、綁定方式、預存程序、交易處理、圖片儲存、表格控件配合等主題。