****************************************************************************************************** 本文關於 ADO 簡介的文字取自 VB 編程樂園 ,特此聲明。 適用範圍:資料庫 適用對象: C++ ,初級 ****************************************************************************************************** 一、 ADO 簡介 ActiveX Data Objects (ADO) 是微軟最新的資料訪問技術。它被設計用來同新的資料訪問層 OLE DB Provider 一起協同工作,以提供通用資料訪問( Universal Data Access )。 OLE DB 是一個低層的資料提供者,用它可以訪問各種資料來源,包括傳統的關係型資料庫,以及電子郵件系統及自訂的商業對象。 ADO 向我們提供了一個熟悉的,高層的對 OLE DB 的 Automation 封裝介面。對那些熟悉 RDO 的程式員來說,你可以把 OLE DB 比作是 ODBC 驅動程式。如同 RDO 對象是 ODBC 驅動程式介面一樣, ADO 對象是 OLE DB 的介面;如同不同的資料庫系統需要它們自己的 ODBC 驅動程式一樣,不同的資料來源要求它們自己的 OLE DB 提供者( OLE DB provider )。目前,雖然 OLE DB 提供者比較少,但微軟正積極推廣該技術,並打算用 OLE DB 取代 ODBC 。 二、在哪裡能得到 ADO? 目前最新版本的已經可以從微軟網站免費下載。到目前為止,微軟網站仍是你擷取有關 ADO 最新資訊的最佳場所。 ADO 是作為 OLE DB SDK 的一部分提供的。你可以從下面這個網址下載: http://www.microsoft.com/data/oledb/download.htm 三、如何使用 ADO 使用 ADO 有許多種方式,最常用的方法是直接使用 Activate 控制項中的 Microsoft ADO Data Control ,這樣用起來很方便。但是大家可能覺得它也有不少的缺點,比如說用起來不夠方便啦,函數的介面都較晦澀難懂等等,總之,就是感覺到不靈活。 今天我為大家介紹一個類,它實質上是對 ADO 的一個封裝,使用起來相當靈活。詳細代碼在附帶的壓縮包 ado.zip 內。 這個類的作者是 Carlos Antollini ,目前的版本為 2.04 ,支援 ado1.5 ,有兩個檔案,分別為 ado.h 和 ado.cpp 。我僅作了少量改動。 庫簡介: 這個庫主要由 6 個部分組成,分別是 CADOCommand (命令處理), CADODatabase (資料庫主體), CADOException (意外處理), CADOFieldInfo (欄位值), CADOParameter (參數), CADORecordset (記錄集)。其中最主要的就是 CAdoCommand 類, CAdoDatabase 類和 CAdoRecordset 。 要使用這個庫,你可能需要安裝以下軟體(我沒有嚴格測試,所以實際上的情況可能略有出入): 1 , MDAC2.8 2 , Microsoft Visual Studio 6.0 使用方法和範例 下面我會以一個串連 sql server 資料庫的例子做示範,逐步展示如何去使用這個庫。 第一步,建立一個對話方塊工程,為主對話方塊添加的幾個控制項 第二步,加入 ado.h 和 ado.cpp ,並且把 MSADO15.DLL 拷到工程 .dsp 所在的目錄 第三步,用 access 建立一個資料庫,添加一張 account 表,添加幾個記錄 第四步,修改代碼如下: // 主對話方塊的標頭檔 #include "ado.h" class CAdoDemoDlg : public CDialog { // Construction public: CAdoDemoDlg(CWnd* pParent = NULL); // standard constructor // 省略系統代碼 private: // 取當前的值 void GetCurrentVal(void); // 設定當前視窗的控制項的資料 void SetControlData(CString strAccount, CString strNick, int nArticle, int nFlower, int nKnife); // 初始化資料庫 BOOL InitDatabase(void); CADORecordset m_pRs; // 資料表 CADODatabase m_pDb; // 資料庫 int nRecordIndex_; // 目前記錄的索引 }; // 主對話方塊的實現檔案 // AdoDemoDlg.cpp : implementation file CAdoDemoDlg::CAdoDemoDlg(CWnd* pParent /*=NULL*/) : CDialog(CAdoDemoDlg::IDD, pParent) // 建構函式 { //… 省略系統代碼 nRecordIndex_ =0; } BOOL CAdoDemoDlg::OnInitDialog() // 初始化對話方塊 { CDialog::OnInitDialog(); //… 省略系統代碼 InitDatabase(); // 初始化資料庫 GetCurrentVal(); // 取當前的記錄值 return TRUE; // return TRUE unless you set the focus to a control } void CAdoDemoDlg::OnDestroy() // 關閉視窗的時候,關閉資料庫 { CDialog::OnDestroy(); if(m_pRs.IsOpen()) { m_pRs.Close(); } if(m_pDb.IsOpen()) { m_pDb.Close(); } } BOOL CAdoDemoDlg::InitDatabase() { // 初始化資料庫 //strConnection, 資料庫連接串, ado 支援各種串連串 CString strConnection ="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=E:// Workspace// AdoDemo//db.mdb;Persist Security Info=False"; if(!m_pDb.Open(strConnection)) // 開啟資料庫 { AfxMessageBox(m_pDb.GetLastErrorString()); return FALSE; } m_pRs = CADORecordset(&m_pDb); // 初始化記錄集 CString strSQL =""; strSQL.Format("SELECT * from account"); CADOCommand cmd(&m_pDb, _T("")); cmd.SetText(strSQL); cmd.SetType(adCmdText); if(!m_pRs.Execute(&cmd)) // 使用 SQL 陳述式產生記錄源 { AfxMessageBox(m_pDb.GetLastErrorString()); return FALSE; } return TRUE; } void CAdoDemoDlg::SetControlData(CString strAccount, CString strNick, int nArticle, int nFlower, int nKnife) { // 設定控制項上顯示的內容 // 帳號 m_Account .SetWindowText(strAccount); // 暱稱 m_Nick .SetWindowText(strNick); CString strNumText; // 貼子數 strNumText .Format("%d", nArticle); m_ArticleCount .SetWindowText(strNumText); // 鮮花 strNumText .Format("%d", nFlower); m_Flower .SetWindowText(strNumText); // 飛刀 strNumText .Format("%d", nKnife); m_Knife .SetWindowText(strNumText); } void CAdoDemoDlg::OnPrev() { // 上一步按鈕的處理 if(!m_pRs.IsOpen()) // 資料庫沒開啟 return ; if(m_pRs.IsBOF()) // 到頂了 return ; if(0 == nRecordIndex_) return ; nRecordIndex_ --; m_pRs.MovePrevious(); GetCurrentVal(); } void CAdoDemoDlg::OnNext() { // 下一步按鈕的處理函數 if(!m_pRs.IsOpen()) // 資料庫沒開啟 return ; if(m_pRs.IsEof() || m_pRs.IsBof()) // 到底了 return ; if(((int)m_pRs.GetRecordCount() - 1) == nRecordIndex_) return ; nRecordIndex_ ++; m_pRs.MoveNext(); GetCurrentVal(); } void CAdoDemoDlg::GetCurrentVal() {// 取目前記錄的資料 if(!m_pRs.IsOpen()) // 資料庫沒開啟 return ; CString strAccount; m_pRs .GetFieldValue(" 帳號 ", strAccount, ""); CString strNick; m_pRs .GetFieldValue(" 暱稱 ", strNick, ""); CString strArticleCount; m_pRs .GetFieldValue(" 發貼數量 ", strArticleCount, ""); CString strFlower; m_pRs .GetFieldValue(" 鮮花數 ", strFlower, ""); CString strKnife; m_pRs .GetFieldValue(" 飛刀數 ", strKnife, ""); SetControlData(strAccount, strNick, atoi(strArticleCount), atoi(strFlower), atoi(strKnife)); } 程式說明 這個示範程式很簡單,只示範了如何查詢一個資料庫,其實資料庫程式確實沒什麼很特別,主要是使用 sql 語句作操作就可以了。 程式的重點在三個函數: 1 , BOOL InitDatabase(void) 這個函數初始化了資料庫 CString strConnection ="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=E:// Workspace// AdoDemo//db.mdb;Persist Security Info=False"; 上面一個語句就產生了一個連接字串 if(!m_pDb.Open(strConnection)) 使用上面產生的語句開啟資料庫 m_pRs = CADORecordset(&m_pDb); 如果資料庫成功開啟,則開啟這個資料庫的表 CString strSQL =""; strSQL.Format("SELECT * from account"); 先產生一個 SQL 陳述式 CADOCommand cmd(&m_pDb, _T("")); cmd.SetText(strSQL); cmd.SetType(adCmdText); 利用 SQL 陳述式產生操作命令 if(!m_pRs.Execute(&cmd)) // 使用 SQL 陳述式產生記錄源 執行這個操作後,資料表就是有效了。 2,OnPrev和OnNext是相似的,拿OnPrev來解釋就行了 if(!m_pRs.IsOpen()) //資料庫沒開啟 return ; if(m_pRs.IsBOF()) //到頂了 return ; 上面代碼先檢查資料庫是否有效,已經表指標是否已經到頂了 if(0 == nRecordIndex_) return ; nRecordIndex有點特別,其實是一個輔助變數,主要是表頭(BOF)和表尾(EOF)跟真實記錄間會有一個記 錄的間隔,所以使用 nRecordIndex作輔助判斷。 nRecordIndex_ --; 向前一個記錄, nRecordIndex減1 m_pRs.MovePrevious(); 表指標向前移一個記錄 GetCurrentVal(); 設定目前記錄的資料 進階 關於ado庫的原理 : 這個庫其實是對於 Microsoft ADO Data Control 一個封裝,它的本質還是 Microsoft ADO Data Control 。只是它把這個組件中一些晦澀的功能函數變成一個簡單易懂的函數,而且使用起來更靈活。基本上 Microsoft ADO Data Control 能做到的東西,它都能做到, Microsoft ADO Data Control 不方便做的東西,它做起來要更方便一些。以 CADODatabase 類為例,它裡面的核心就是: _ConnectionPtr m_pConnection ! |