作者:浙江省溫嶺市電信公司 王駿
一、ADO簡介 二、基本流程 準備工作: BOOL CADOTest1App::InitInstance() { AfxOleInit(); ......【2】用#import指令引入ADO類型庫 我們在stdafx.h中加入如下語句:(stdafx.h這個文件哪裏可以找到?你可以在FileView中的Header Files裏找到) #import "c:/program files/common files/system/ado/msado15.dll" no_namespace rename("EOF","adoEOF") 這一語句有何作用呢?其最終作用同我們熟悉的#include類似,編譯的時候系統會爲我們生成msado15.tlh,ado15.tli兩個C++頭文件來定義ADO庫。 【3】創建Connection對象並連接數據庫 BOOL CADOTest1Dlg::OnInitDialog() { CDialog::OnInitDialog(); 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; 在這段代碼中我們是通過Connection對象的Open方法來進行連接數據庫的,下面是該方法的原型 我們給出一些常用的連接方式供大家參考: 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 m_pConnection->Execute("CREATE TABLE users(ID INTEGER,username TEXT,old INTEGER,birthday DATETIME)",&RecordsAffected,adCmdText); ///往表格裏面添加記錄 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方法的原型是這樣的:
_variant_t vUsername,vBirthday,vID,vOld; _RecordsetPtr m_pRecordset; m_pRecordset.CreateInstance("ADODB.Recordset"); m_pRecordset->Open("SELECT * FROM users",_variant_t((IDispatch*)m_pConnection,true),adOpenStatic,adLockOptimistic,adCmdText); while(!m_pRecordset->adoEOF)///這裏爲什麼是adoEOF而不是EOF呢?還記得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();///移到下一條記錄 } m_pRecordset->MoveFirst();///移到首條記錄 m_pRecordset->Delete(adAffectCurrent);///刪除當前記錄 ///添加三條新記錄並賦值 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")); } m_pRecordset->Move(1,_variant_t((long)adBookmarkFirst));///從第一條記錄往下移動一條記錄,即移動到第二條記錄處 m_pRecordset->PutCollect(_variant_t("old"),_variant_t((long)45));///修改其年齡 m_pRecordset->Update();///保存到庫中【6】關閉記錄集與連接 記錄集或連接都可以用Close方法來關閉 m_pRecordset->Close();///關閉記錄集 m_pConnection->Close();///關閉連接 |