(1)初始化COM庫,引入ADO庫定義檔案
(2)用Connection對象連接配接資料庫
(3)利用建立好的連接配接,通過Connection、Command對象執行SQL指令,或利用Recordset對象取得結果記錄集進行查詢、處理。
(4)使用完畢後關閉連接配接釋放對象。
【1】COM庫的初始化:
我們可以使用AfxOleInit()來初始化COM庫,這項工作通常在CWinApp::InitInstance()的重載函數中完成,請看如下代碼:
BOOL CADOTest1App::InitInstance()
{
if(!AfxOleInit())
{
AfxMessageBox("OLE初始化出錯!");
return FALSE;
}
...
}
【2】用#import指令引入ADO類型庫:
在stdafx.h中加入如下語句:
#import "c:/program files/common files/system/ado/msado15.dll" no_namespace rename ("EOF","adoEOF")
其最終作用同我們熟悉的#include類似,編譯的時候系統會為我們生成msado15.tlh,ado15.tli兩個C++頭檔案來定義ADO庫。
【3】建立Connection對象并連接配接資料庫:
首先我們需要添加一個指向Connection對象的指針.
下面的代碼示範了如何建立Connection對象執行個體及如何連接配接資料庫并進行異常捕捉。
BOOL CADOTest1Dlg::OnInitDialog()
{
CDialog::OnInitDialog();
_ConnectionPtr m_pConnection;
HRESULT hr;
try
{
hr = m_pConnection.CreateInstance("ADODB.Connection");///建立Connection對象
if(SUCCEEDED(hr))
hr = m_pConnection->Open("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=test.mdb","","",adModeUnknown);///連接配接資料庫
///上面一句中連接配接字串中的Provider是針對ACCESS2000環境的,對于ACCESS97,需要改為:Provider=Microsoft.Jet.OLEDB.3.51; }
}
catch(_com_error e)///捕捉異常
{
CString errormessage;
errormessage.Format("連接配接資料庫失敗!/r/n錯誤資訊:%s",e.ErrorMessage());
AfxMessageBox(errormessage);///顯示錯誤資訊
}
...
在這段代碼中我們是通過Connection對象的Open方法來進行連接配接資料庫的,下面是該方法的原型:
HRESULT Connection15::Open ( _bstr_t ConnectionString,
_bstr_t UserID,
_bstr_t Password,
long Options )
ConnectionString為連接配接字串,
UserID是使用者名,
Password是登陸密碼,
Options是連接配接選項,用于指定Connection對象對資料的更新許可權,
Options可以是如下幾個常量:
adModeUnknown: 預設。目前的許可權未設定
adModeRead: 隻讀
adModeWrite: 隻寫
adModeReadWrite:可以讀寫
adModeShareDenyRead:阻止其它Connection對象以讀權限打開連接配接
adModeShareDenyWrite:阻止其它Connection對象以寫權限打開連接配接
adModeShareExclusive:阻止其它Connection對象打開連接配接
adModeShareDenyNone:允許其它程式或對象以任何權限建立連接配接
一些常用的連接配接方式:
(1)通過JET資料庫引擎對ACCESS2000資料庫的連接配接
m_pConnection->Open("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C://test.mdb",
"","",
adModeUnknown);
(2)通過DSN資料源對任何支援ODBC的資料庫進行連接配接:
m_pConnection->Open("Data Source=adotest;UID=sa;PWD=;","","",adModeUnknown);
(3)不通過DSN對SQL SERVER資料庫進行連接配接:
m_pConnection->Open("driver={SQL Server};Server=127.0.0.1;DATABASE=vckbase;UID=sa;PWD=139",
"","",
adModeUnknown);
其中Server是SQL伺服器的名稱,DATABASE是庫的名稱
Connection對象除Open方法外還有許多方法,我們先介紹Connection對象中兩個有用的屬性ConnectionTimeOut與State:
ConnectionTimeOut用來設定連接配接的逾時時間,需要在Open之前調用,例如:
m_pConnection->ConnectionTimeout = 5;///設定逾時時間為5秒
m_pConnection->Open("Data Source=adotest;","","",adModeUnknown);
State屬性指明目前Connection對象的狀态,0表示關閉,1表示已經打開,我們可以通過讀取這個屬性來作相應的處理,例如:
if(m_pConnection->State)
m_pConnection->Close(); ///如果已經打開了連接配接則關閉它
【4】執行SQL指令并取得結果記錄集
為了取得結果記錄集,我們定義一個指向Recordset對象的指針:_RecordsetPtr m_pRecordset;
并為其建立Recordset對象的執行個體: m_pRecordset.CreateInstance("ADODB.Recordset");
SQL指令的執行可以采用多種形式,下面我們一進行闡述。
(1)利用Connection對象的Execute方法執行SQL指令
Execute方法的原型如下所示:
_RecordsetPtr Connection15::Execute ( _bstr_t CommandText,
VARIANT * RecordsAffected,
long Options )
其中CommandText是指令字串,通常是SQL指令。
參數RecordsAffected是操作完成後所影響的行數,
參數Options表示CommandText中内容的類型,
Options可以取如下值之一:
adCmdText:表明CommandText是文本指令
adCmdTable:表明CommandText是一個表名
adCmdProc:表明CommandText是一個存儲過程
adCmdUnknown:未知
Execute執行完後傳回一個指向記錄集的指針,下面給出具體代碼并作說明。
_variant_t RecordsAffected;
///執行SQL指令:CREATE TABLE建立表格users,users包含四個字段:整形ID,字元串username,整形old,日期型birthday
try
{
hr=m_pConnection->Execute("CREATE TABLE users22(ID INTEGER,username TEXT,old INTEGER, /
birthday DATETIME)",&RecordsAffected,adCmdText);
}
catch(_com_error e)///捕捉異常,如果表已經存在,則直接寫資料.
{
CString errormessage;
errormessage.Format("建立資料表失敗!/r/n錯誤資訊:%s",e.ErrorMessage());
AfxMessageBox(errormessage);///顯示錯誤資訊
AfxMessageBox("錯誤源是: " + e.Source());
AfxMessageBox("錯誤描述: " + e.Description());
}
///往表格裡面添加記錄
m_pConnection->Execute("INSERT INTO users(ID,username,old,birthday) VALUES (1,'Washington',25,'1970/1/1')",&RecordsAffected,adCmdText);
///将所有記錄old字段的值加一
m_pConnection->Execute("UPDATE users SET old = old+1",&RecordsAffected,adCmdText);
///執行SQL統計指令得到包含記錄條數的記錄集
m_pRecordset = m_pConnection->Execute("SELECT COUNT(*) FROM users",&RecordsAffected,adCmdText);
_variant_t vIndex = (long)0;
_variant_t vCount = m_pRecordset->GetCollect(vIndex);///取得第一個字段的值放入vCount變量
m_pRecordset->Close();///關閉記錄集
CString message;
message.Format("共有%d條記錄",vCount.lVal);
AfxMessageBox(message);///顯示目前記錄條數
(2)利用Command對象來執行SQL指令
_CommandPtr m_pCommand;
m_pCommand.CreateInstance("ADODB.Command");
_variant_t vNULL;
vNULL.vt = VT_ERROR;
vNULL.scode = DISP_E_PARAMNOTFOUND;///定義為無參數
m_pCommand->ActiveConnection = m_pConnection;///非常關鍵的一句,将建立的連接配接指派給它
m_pCommand->CommandText = "SELECT * FROM users";///指令字串
m_pRecordset = m_pCommand->Execute(&vNULL,&vNULL,adCmdText);///執行指令,取得記錄集
在這段代碼中隻是用Command對象來執行了SELECT查詢語句,Command對象在進行存儲過程的調用中能真正展現它的作用。下次我們将詳細介紹。
(3)直接用Recordset對象進行查詢取得記錄集
m_pRecordset->Open("SELECT * FROM users",
_variant_t((IDispatch *)m_pConnection,true),
adOpenStatic,
adLockOptimistic,
adCmdText);
Open方法的原型是這樣的:
HRESULT Recordset15::Open ( const _variant_t & Source,
const _variant_t & ActiveConnection,
enum CursorTypeEnum CursorType,
enum LockTypeEnum LockType,
long Options )
其中:
①Source是資料查詢字元串
②ActiveConnection是已經建立好的連接配接(我們需要用Connection對象指針來構造一個_variant_t對象)
③CursorType光标類型,它可以是以下值之一,請看這個枚舉結構:
enum CursorTypeEnum
{
adOpenUnspecified = -1,///不作特别指定
adOpenForwardOnly = 0,///前滾靜态光标。這種光标隻能向前浏覽記錄集,比如用MoveNext向前滾動,這種方式可以提高浏覽速度。但諸如 BookMark,RecordCount,AbsolutePosition,AbsolutePage都不能使用
adOpenKeyset = 1,///采用這種光标的記錄集看不到其它使用者的新增、删除操作,但對于更新原有記錄的操作對你是可見的。
adOpenDynamic = 2,///動态光标。所有資料庫的操作都會立即在各使用者記錄集上反應出來。
adOpenStatic = 3///靜态光标。它為你的記錄集産生一個靜态備份,但其它使用者的新增、删除、更新操作對你的記錄集來說是不可見的。
};
④LockType鎖定類型,它可以是以下值之一,請看如下枚舉結構:
enum LockTypeEnum
{
adLockUnspecified = -1,///未指定
adLockReadOnly = 1,///隻讀記錄集
adLockPessimistic = 2,悲觀鎖定方式。資料在更新時鎖定其它所有動作,這是最安全的鎖定機制
adLockOptimistic = 3,樂觀鎖定方式。隻有在你調用Update方法時才鎖定記錄。在此之前仍然可以做資料的更新、插入、删除等動作
adLockBatchOptimistic = 4,樂觀分批更新。編輯時記錄不會鎖定,更改、插入及删除是在批處理模式下完成。
};
⑤Options參考Connection對象的Execute方法.
【5】記錄集的周遊、更新
根據我們剛才通過執行SQL指令建立好的users表,
它包含四個字段:ID,username,old,birthday
以下的代碼實作打開記錄集及:
1周遊所有記錄,
2删除第一條記錄,
3添加三條記錄,
4移動光标到第二條記錄,更改其年齡,儲存到資料庫。
5關閉記錄集與連接配接
_variant_t vUsername,vBirthday,vID,vOld;
m_pRecordset->Open("SELECT * FROM users",_variant_t((IDispatch*)m_pConnection,true),adOpenStatic,adLockOptimistic,adCmdText);
//*1周遊所有記錄
while(!m_pRecordset->adoEOF)//rename("EOF","adoEOF")
{
vID = m_pRecordset->GetCollect(_variant_t((long)0));///取得第1列的值,從0開始計數,你也可以直接給出列的名稱,如下一行
vUsername = m_pRecordset->GetCollect("username");///取得username字段的值
vOld = m_pRecordset->GetCollect("old");
vBirthday = m_pRecordset->GetCollect("birthday");
//在DEBUG方式下的OUTPUT視窗輸出記錄集中的記錄
if(vID.vt != VT_NULL && vUsername.vt != VT_NULL && vOld.vt != VT_NULL && vBirthday.vt != VT_NULL)
TRACE("id:%d,姓名:%s,年齡:%d,生日:%s/r/n",vID.lVal,(LPCTSTR)(_bstr_t)vUsername,vOld.lVal,(LPCTSTR)(_bstr_t)vBirthday);
m_pRecordset->MoveNext();///移到下一條記錄
}
//*2删除第一條記錄
m_pRecordset->MoveFirst();///移到首條記錄
m_pRecordset->Delete(adAffectCurrent);///删除目前記錄
//*3添加三條新記錄并指派
for(int i=0;i<3;i++)
{
m_pRecordset->AddNew();///添加新記錄
m_pRecordset->PutCollect("ID",_variant_t((long)(i+10)));
m_pRecordset->PutCollect("username",_variant_t("葉利欽"));
m_pRecordset->PutCollect("old",_variant_t((long)71));
m_pRecordset->PutCollect("birthday",_variant_t("1930-3-15"));
}
//*4移動光标到第二條記錄,更改其年齡,儲存到資料庫。
m_pRecordset->Move(1,_variant_t((long)adBookmarkFirst));///從第一條記錄往下移動一條記錄,即移動到第二條記錄處
m_pRecordset->PutCollect(_variant_t("old"),_variant_t((long)45));///修改其年齡
m_pRecordset->Update();
//*5關閉記錄集與連接配接
//記錄集或連接配接都可以用Close方法來關閉
m_pRecordset->Close();///關閉記錄集
m_pConnection->Close();///關閉連接配接
【6】關閉記錄集與連接配接
記錄集或連接配接都可以用Close方法來關閉
m_pRecordset->Close();///關閉記錄集
m_pConnection->Close();///關閉連接配接
至此,ADO操作資料庫的大緻流程完成.
為了您的安全,請隻打開來源可靠的網址
打開網站 取消
來自: http://hi.baidu.com/ljfblog/blog/item/4ef40a4c7576a7f9d72afce2.html