傳統 ADO 透過 VARIANT 傳遞資料,類型轉換效能低且程式碼冗長。ADO 2.0 引入 VC++ Extensions,提供:
int, char[], float 等)。BEGIN_ADO_BINDING 等)。VARIANT 轉換與狀態檢查,效能大幅提升。每個欄位對應一個 繫結條目,由巨集定義:
ADO_VARIABLE_LENGTH_ENTRY2(ordinal, wType, pBuffer, ulSize, pStatus, bBind)
adVarChar, adInteger 等)。ULONG),回傳 adFldOK 成功、adFldNull 為 NULL 等。TRUE 允許更新,FALSE 唯讀。
// ADOTest.h
#import "C:\\Program Files\\Common Files\\System\\ADO\\msado15.dll" \
no_namespace rename("EOF", "EndOfFile")
#include // VC++ Extensions 巨集
class CAuthorsRs : public CADORecordBinding {
BEGIN_ADO_BINDING(CAuthorsRs)
ADO_VARIABLE_LENGTH_ENTRY2(1, adVarChar, m_au_fname, sizeof(m_au_fname), m_lfnameSt, TRUE)
ADO_VARIABLE_LENGTH_ENTRY2(2, adVarChar, m_au_lname, sizeof(m_au_lname), m_llnameSt, TRUE)
ADO_VARIABLE_LENGTH_ENTRY2(3, adVarChar, m_au_city, sizeof(m_au_city), m_lcitySt, TRUE)
ADO_VARIABLE_LENGTH_ENTRY2(4, adChar, m_au_state, sizeof(m_au_state), m_lstateSt, TRUE)
END_ADO_BINDING()
public:
char m_au_fname[21]; ULONG m_lfnameSt;
char m_au_lname[41]; ULONG m_llnameSt;
char m_au_city[21]; ULONG m_lcitySt;
char m_au_state[3]; ULONG m_lstateSt;
};
// main.cpp
#include
#include
#include "ADOTest.h"
void main() {
if (FAILED(CoInitialize(NULL))) return;
_RecordsetPtr pRs = NULL;
IADORecordBinding* pBind = NULL;
CAuthorsRs rs;
HRESULT hr;
_bstr_t connStr("Provider=sqloledb;Data Source=nt_sqlserver;Initial Catalog=pubs;User Id=sa;Password=;");
try {
// 建立 Recordset
hr = pRs.CreateInstance(__uuidof(Recordset));
pRs->CursorType = adOpenStatic;
pRs->CursorLocation = adUseClient; // 支援 AbsolutePosition
pRs->Open("SELECT au_fname, au_lname, city, state FROM Authors ORDER BY au_id",
connStr, adOpenStatic, adLockReadOnly, adCmdText);
// 取得繫結介面並繫結
hr = pRs->QueryInterface(__uuidof(IADORecordBinding), (void**)&pBind);
hr = pBind->BindToRecordset(&rs);
pRs->MoveFirst();
while (!pRs->EndOfFile) {
printf("Record %ld of %ld\n", pRs->AbsolutePosition, pRs->RecordCount);
printf("Author: %s %s\n",
rs.m_lfnameSt == adFldOK ? rs.m_au_fname : "",
rs.m_llnameSt == adFldOK ? rs.m_au_lname : "");
printf("Location: %s, %s\n\n",
rs.m_lcitySt == adFldOK ? rs.m_au_city : "",
rs.m_lstateSt == adFldOK ? rs.m_au_state : "");
pRs->MoveNext();
}
}
catch (_com_error& e) {
printf("Error: 0x%08lx - %s\n", e.Error(), e.ErrorMessage());
}
if (pRs) pRs->Close();
if (pBind) pBind->Release();
CoUninitialize();
}
VARIANT 封裝/解封裝開銷。pStatus 即時告知 NULL/截斷/轉換錯誤。bBind=TRUE 並使用 adLockOptimistic 即可直接修改緩衝區並 Update 寫回資料庫。ADO VC++ Extensions 是 C/C++ 開發者存取資料庫的利器,將 ADO 的易用性與原生效能完美結合,強烈建議在高效能資料存取場合採用。