1、使用ADO編程的方法有三種:
(1)使用預處理指令#import,例如:
#import "c:\Program Files\Common Files\System\ado\msado15.dll" no_namespace rename("EOF", "adoEOF") rename("BOF", "adoBOF")
程序在編譯時讀取msado15.dll中的類型庫信息,自動生成兩個該類型庫的頭文件和實現文件msado15.tlh和msado15.tli(在Debug或Release目錄下)。兩個文件中定義了ADO的所有對象和方法,以及一些枚舉類型的變量,程序只要直接調用這些方法即可。
(2)通過讀取msado15.dll中的類型庫信息,建立一個ColeDispatchDriver類的派生類,然後通過它調用ADO對象。
(3)直接使用COM提供的API,例如:
CLSID clsid;
HRESULT hr = ::CLSIDFromProgID(L"ADODB.Connection", &clsid);
if (FAILED(hr))
{
...
}
::CoCreateInstance(clsid, NULL, CLSCTX_SERVER, IID_IDispatch, (void **)&pDispatch);
if (FAILED(hr))
{
...
}
前兩種方法類似,第3種方法編程可能最麻煩,但效率最高,程序尺寸最小,並且對ADO的控制能力也最強。
2、以下使用#import方法操作數據庫
(1)可以在stdafx.h的所有include指令之後import
(2)使用AfxOleInit()初始化COM庫,通常在CwinApp::InitInstance的重載函數中添加。
(也可以使用::CoInitialize(NULL),之後在ExitInstance中調用::CoUninitialize)
(3)定義_ConnectionPtr變量後調用Connection對象的Open方法建立與服務器的連接。
數據類型_ConnectionPtr實際上是由類模板_com_ptr_t得到的一個具體的實例類。_ConnectionPtr類封裝了Connection對象的Idispatch接口指針及其一些必要的操作。可以通過這個指針操縱Connection對象。
例如連接SQLServer數據庫,代碼如下:
// 連接到MS SQL Server
_ConnectionPtr pMyConnect = NULL;
HRESULT hr = pMyConnect.CreateInstance(__uuidof(Connection));
if (FAILED(hr))
return;
_bstr_t strConnect = "Provider=SQLOLEDB; Server=hch; Database=mytest; uid=sa; pwd=sa;";
try
{
// Open方法連接字串必須四BSTR或者_bstr_t類型
pMyConnect->Open(strConnect, "", "", NULL);
}
catch(_com_error &e)
{
MessageBox(e.Description(), "警告", MB_OK|MB_ICONINFORMATION);
}
(4)
//定義_RecordsetPtr變量,調用它Recordset對象的Open,即可打開一個數據集
_RecordsetPtr pRecordset;
if (FAILED(pRecordset.CreateInstance(__uuidof(Recordset))))
{
return;
}
try
{
pRecordset->Open(_variant_t("userinfo"), _variant_t((IDispatch*)pMyConnect),
adOpenKeyset, adLockOptimistic, adCmdTable);
}
catch (_com_error &e)
{
MessageBox("無法打開userinfo表", "系統提示", MB_OK|MB_ICONINFORMATION);
}
(5)
//定義_RecordsetPtr變量,調用它Recordset對象的Open,即可打開一個數據集
_RecordsetPtr pRecordset;
if (FAILED(pRecordset.CreateInstance(__uuidof(Recordset))))
{
return;
}
try
{
pRecordset->Open(_variant_t("userinfo"), _variant_t((IDispatch*)pMyConnect),
adOpenKeyset, adLockOptimistic, adCmdTable);
}
catch (_com_error &e)
{
MessageBox("無法打開userinfo表", "系統提示", MB_OK|MB_ICONINFORMATION);
}
(6)
// 讀取當前記錄集
try
{
pRecordset->MoveFirst();
while (pRecordset->adoEOF == VARIANT_FALSE)
{
// Fields是Recordset對象的容器,GetItem方法返回Field對象,Value是FIEld對象的屬性,也可以用GetValue方法
CString sName = (char*)(_bstr_t)(pRecordset->FIElds->GetItem(_variant_t("UserName"))->Value);
// 或者使用GetValue()
//CString sName = (char*)(_bstr_t)(pRecordset->FIElds->GetItem(_variant_t("UserName"))->GetValue());
AfxMessageBox(sName);
pRecordset->MoveNext();
}
}
catch (_com_error &e)
{
MessageBox(e.Description(), "系統提示", MB_OK|MB_ICONINFORMATION);
}
(7)
// 修改記錄
try
{
pRecordset->MoveFirst();
while(pRecordset->adoEOF == VARIANT_FALSE)
{
pRecordset->FIElds->GetItem(_variant_t("Address"))->Value = _bstr_t("北京大學");
pRecordset->Update();
pRecordset->MoveNext();
}
}
catch (_com_error &e)
{
MessageBox(e.Description(), "系統提示",