ADO (ActiveX Data Objects) 是 Windows 平台訪問 Access、SQL Server、Oracle 等資料庫的標準 COM 介面。本文提供一個封裝良好的 CADODB 類,整合 #import msado15.dll、連接字串 (.udl 檔案)、_ConnectionPtr/_RecordsetPtr/_CommandPtr 智慧指標、SQL 執行與記錄集遍歷,支援對話框專案直接使用。
#import "C:\\Program Files\\Common Files\\System\\ado\\msado15.dll" \
no_namespace rename("EOF", "adoEOF") // 避免與 C++ EOF 巨集衝突
CWinApp::InitInstance 最前呼叫 AfxOleInit() 或 CoInitialize(NULL)。config.udl,雙擊用「資料連結屬性」對話框圖形化配置 (Provider: Microsoft Jet 4.0 OLE DB Provider, 資料來源: db.mdb),連接字串即為 File Name=config.udl,部署時只需修改 .udl 檔無需改代碼。class CADODB {
public:
_ConnectionPtr m_pConn;
_RecordsetPtr m_pRs;
_CommandPtr m_pCmd;
BOOL m_bOpen;
CString m_strSQL;
CADODB();
void Open(); // 開啟連接
void Close(); // 關閉並釋放
BOOL Execute(CString sql); // INSERT/UPDATE/DELETE
_RecordsetPtr Query(CString sql); // SELECT 返回記錄集
};
extern CADODB g_db; // 全域實例 (或作成員變數)
CADODB g_db;
CADODB::CADODB() : m_bOpen(FALSE) {}
void CADODB::Open() {
if (m_bOpen) return;
m_pConn.CreateInstance(__uuidof(Connection));
m_pRs.CreateInstance(__uuidof(Recordset));
m_pCmd.CreateInstance(__uuidof(Command));
TCHAR path[MAX_PATH]; GetCurrentDirectory(MAX_PATH, path);
CString udlPath; udlPath.Format(_T("%s\\config.udl"), path);
CString connStr; connStr.Format(_T("File Name=%s"), udlPath);
m_pConn->ConnectionString = (_bstr_t)connStr;
m_pConn->Open(_T(""), _T(""), _T(""), adConnectUnspecified); // udl 內含帳密
m_pCmd->ActiveConnection = m_pConn;
m_bOpen = TRUE;
}
void CADODB::Close() {
if (!m_bOpen) return;
m_pConn->Close();
m_pConn.Release(); m_pRs.Release(); m_pCmd.Release();
m_bOpen = FALSE;
}
BOOL CADODB::Execute(CString sql) {
if (!m_bOpen) return FALSE;
m_pCmd->CommandText = (_bstr_t)sql;
m_pCmd->Execute(NULL, NULL, adCmdText);
return TRUE;
}
_RecordsetPtr CADODB::Query(CString sql) {
if (!m_bOpen) return NULL;
m_pCmd->CommandText = (_bstr_t)sql;
return m_pCmd->Execute(NULL, NULL, adCmdText);
}
g_db.m_strSQL = _T("SELECT * FROM MyTable");
g_db.Open();
g_db.m_pRs = g_db.Query(g_db.m_strSQL);
while (!g_db.m_pRs->adoEOF) { // 注意: adoEOF (rename 後)
// _variant_t -> CString 轉換
_variant_t vName = g_db.m_pRs->GetCollect(_T("NAME"));
CString strName = (LPCTSTR)(_bstr_t)vName; // _variant_t -> _bstr_t -> LPCTSTR
// ... 使用 strName ...
g_db.m_pRs->MoveNext();
}
g_db.Close();
g_db.m_strSQL.Format(_T("INSERT INTO MyTable(NAME,AGE) VALUES('%s',%d)"), myName, age);
g_db.Open();
g_db.Execute(g_db.m_strSQL);
g_db.Close();
g_db.m_strSQL = _T("SELECT MAX(ID) AS mID FROM MyTable");
g_db.m_pRs = g_db.Query(g_db.m_strSQL);
_variant_t vMax = g_db.m_pRs->GetCollect(_T("mID"));
int newID = (vMax.vt == VT_NULL) ? 1 : (vMax.lVal + 1);
| ADO 類型 | 轉 CString | 轉 int/double |
|---|---|---|
_variant_t | (LPCTSTR)(_bstr_t)var | var.lVal / var.dblVal |
_bstr_t | (LPCTSTR)bstr | _wtoi(bstr) / _wtof(bstr) |
_ConnectionPtr 等離開作用域自動 Release,無記憶體洩漏。此封裝類已在多個 Access/SQL Server 專案中穩定服役。