下面讓我們看看ADO資料庫通路技術使用的基本步驟及方法: 首先,要用#import 語句來引用支援ADO的元件類型庫(*.tlb),其中類型庫可以作為可執行程式(DLL、EXE等)的一部分被定位在其自身程式中的附屬資源裡,如:被 定位在msado15.dll的附屬資源中,隻需要直接用#import引用它既可。可以直接在Stdafx.h檔案中加入下面語句來實作: #import "c:/program files/common files/system/ado/msado15.dll" / no_namespace / rename ("EOF", "adoEOF") 其 中路徑名可以根據自己系統安裝的ADO支援檔案的路徑來自行設定。當編譯器遇到#import語句時,它會為引用元件類型庫中的接口生成包裝 類,#import語句實際上相當于執行了API涵數LoadTypeLib()。#import語句會在工程可執行程式輸出目錄中産生兩個檔案,分别 為*.tlh(類型庫頭檔案)及*.tli(類型庫實作檔案),它們分别為每一個接口産生智能指針,并為各種接口方法、枚舉類型,CLSID等進行聲明, 建立一系列包裝方法。語句no_namespace說明ADO對象不使用命名空間,rename ("EOF", "adoEOF")說明将ADO中結束标志EOF改為adoEOF,以避免和其它庫中命名相沖突。 其次,在程式初始過程中需要初始化元件,一般可 以用CoInitialize(NULL);來實作,這種方法在結束時要關閉初始化的COM,可以用下面語句CoUnInitialize();來實作。 在MFC中還可以采用另一種方法來實作初始化COM,這種方法隻需要一條語句便可以自動為我們實作初始化COM和結束時關閉COM的操作,語句如下所示: AfxOleInit(); 接着,就可以直接使用ADO的操作了。我們經常使用的隻是前面用#import語句引用類型庫時,生成的包裝 類.tlh中聲明的智能指針中的三個,它們分别是_ConnectionPtr、_RecordsetPtr和_CommandPtr。下面分别對它們的 使用方法進行介紹: 1、_ConnectionPtr智能指針,通常用于打開、關閉一個庫連接配接或用它的Execute方法來執行一個不傳回結果的指令語句(用法和_CommandPtr中的Execute方法類似)。 ——打開一個庫連接配接。先建立一個執行個體指針,再用Open打開一個庫連接配接,它将傳回一個IUnknown的自動化接口指針。代碼如下所示: _ConnectionPtr m_pConnection; // 初始化COM,建立ADO連接配接等操作 AfxOleInit(); m_pConnection.CreateInstance(__uuidof(Connection)); // 在ADO操作中建議語句中要常用try...catch()來捕獲錯誤資訊, // 因為它有時會經常出現一些意想不到的錯誤。jingzhou xu try { // 打開本地Access庫Demo.mdb m_pConnection->Open("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=Demo.mdb","","",adModeUnknown); } catch(_com_error e) { AfxMessageBox("資料庫連接配接失敗,确認資料庫Demo.mdb是否在目前路徑下!"); return FALSE; } ——關閉一個庫連接配接。如果連接配接狀态有效,則用Close方法關閉它并賦于它空值。代碼如下所示: if(m_pConnection->State) m_pConnection->Close(); m_pConnection= NULL; 2、_RecordsetPtr智能指針,可以用來打開庫内資料表,并可以對表内的記錄、字段等進行各種操作。 ——打開資料表。打開庫内表名為DemoTable的資料表,代碼如下: _RecordsetPtr m_pRecordset; m_pRecordset.CreateInstance(__uuidof(Recordset)); // 在ADO操作中建議語句中要常用try...catch()來捕獲錯誤資訊, // 因為它有時會經常出現一些意想不到的錯誤。jingzhou xu try { m_pRecordset->Open("SELECT * FROM DemoTable", // 查詢DemoTable表中所有字段 theApp.m_pConnection.GetInterfacePtr(), // 擷取庫接庫的IDispatch指針 adOpenDynamic, adLockOptimistic, adCmdText); } catch(_com_error *e) { AfxMessageBox(e->ErrorMessage()); } —— 讀取表内資料。将表内資料全部讀出并顯示在清單框内,m_AccessList為清單框的成員變量名。如果沒有遇到表結束标志adoEOF,則用 GetCollect(字段名)或m_pRecordset->Fields->GetItem(字段名)->Value方法,來擷取 目前記錄指針所指的字段值,然後再用MoveNext()方法移動到下一條記錄位置。代碼如下所示: _variant_t var; CString strName,strAge; try { if(!m_pRecordset->BOF) m_pRecordset->MoveFirst(); else { AfxMessageBox("表内資料為空"); return; } // 讀入庫中各字段并加入清單框中 while(!m_pRecordset->adoEOF) { var = m_pRecordset->GetCollect("Name"); if(var.vt != VT_NULL) strName = (LPCSTR)_bstr_t(var); var = m_pRecordset->GetCollect("Age"); if(var.vt != VT_NULL) strAge = (LPCSTR)_bstr_t(var); m_AccessList.AddString( strName + " --> "+strAge ); m_pRecordset->MoveNext(); } // 預設清單指向第一項,同時移動記錄指針并顯示 m_AccessList.SetCurSel(0); } catch(_com_error *e) { AfxMessageBox(e->ErrorMessage()); } ——插入記錄。可以先用AddNew()方法新增一個空記錄,再用PutCollect(字段名,值)輸入每個字段的值,最後再Update()更新到庫中資料既可。其中變量m_Name和m_Age分别為姓名及年齡編輯框的成員變量名。代碼所下所示: try { // 寫入各字段值 m_pRecordset->AddNew(); m_pRecordset->PutCollect("Name", _variant_t(m_Name)); m_pRecordset->PutCollect("Age", atol(m_Age)); m_pRecordset->Update(); AfxMessageBox("插入成功!"); } catch(_com_error *e) { AfxMessageBox(e->ErrorMessage()); } —— 移動記錄指針。移動記錄指針可以通過MoveFirst()方法移動到第一條記錄、MoveLast()方法移動到最後一條記錄、 MovePrevious()方法移動到目前記錄的前一條記錄、MoveNext()方法移動到目前記錄的下一條記錄。但我們有時經常需要随意移動記錄指 針到任意記錄位置時,可以使用Move(記錄号)方法來實作,注意: Move()方法是相對于目前記錄來移動指針位置的,正值向後移動、負值向前移動,如:Move(3),目前記錄是3時,它将從記錄3開始往後再移動3條 記錄位置。代碼如下所示: try { int curSel = m_AccessList.GetCurSel(); // 先将指針移向第一條記錄,然後就可以相對第一條記錄來随意移動記錄指針 m_pRecordset->MoveFirst(); m_pRecordset->Move(long(curSel)); } catch(_com_error *e) { AfxMessageBox(e->ErrorMessage()); } ——修改記錄中字段值。可以将記錄指針移動到要修改記錄的位置處,直接用PutCollect(字段名,值)将新值寫入并Update()更新資料庫既可。可以用上面方法移動記錄指針,修改字段值代碼如下所示: try { // 假設對第二條記錄進行修改 m_pRecordset->MoveFirst(); m_pRecordset->Move(1); // 從0開始 m_pRecordset->PutCollect("Name", _variant_t(m_Name)); m_pRecordset->PutCollect("Age", atol(m_Age)); m_pRecordset->Update(); } catch(_com_error *e) { AfxMessageBox(e->ErrorMessage()); } ——删除記錄。删除記錄和上面修改記錄的操作類似,先将記錄指針移動到要修改記錄的位置,直接用Delete()方法删除它并用Update()來更新資料庫既可。代碼如下所示: try { // 假設删除第二條記錄 m_pRecordset->MoveFirst(); m_pRecordset->Move(1); // 從0開始 m_pRecordset->Delete(adAffectCurrent); // 參數adAffectCurrent為删除目前記錄 m_pRecordset->Update(); } catch(_com_error *e) { AfxMessageBox(e->ErrorMessage()); } ——關閉記錄集。直接用Close方法關閉記錄集并賦于其空值。代碼如下所示: m_pRecordset->Close(); m_pRecordset = NULL; 3、CommandPtr智能指針,可以使用_ConnectionPtr或_RecordsetPtr來執行任務,定義輸出參數,執行存儲過程或SQL語句。 ——執行SQL語句。先建立一個_CommandPtr執行個體指針,再将庫連接配接和SQL語句做為參數,執行Execute()方法既可。代碼如下所示: _CommandPtr m_pCommand; m_pCommand.CreateInstance(__uuidof(Command)); m_pCommand->ActiveConnection = m_pConnection; // 将庫連接配接賦于它 m_pCommand->CommandText = "SELECT * FROM DemoTable"; // SQL語句 m_pRecordset = m_pCommand->Execute(NULL, NULL,adCmdText); // 執行SQL語句,傳回記錄集 —— 執行存儲過程。執行存儲過程的操作和上面執行SQL語句類似,不同點僅是CommandText參數中不再是SQL語句,而是存儲過程的名字,如 Demo。另一個不同點就是在Execute()中參數由adCmdText(執行SQL語句),改為adCmdStoredProc來執行存儲過程。如 果存儲過程中存在輸入、輸出參數的話,需要使用到另一個智能指針_ParameterPtr來逐次設定要輸入、輸出的參數資訊,并将其賦于 _CommandPtr中Parameters參數來傳遞資訊,有興趣的讀者可以自行查找相關書籍或MSDN。執行存儲過程的代碼如下所示: _CommandPtr m_pCommand; m_pCommand.CreateInstance(__uuidof(Command)); m_pCommand->ActiveConnection = m_pConnection; // 将庫連接配接賦于它 m_pCommand->CommandText = "Demo"; m_pCommand->Execute(NULL,NULL, adCmdStoredProc); 最後,如果想知道詳細實作細節的話,可以在下載下傳示例源碼後,仔細檢視源碼既可(内有詳細注釋)。 |