Visual C++ 中的ODBC编程
生活随笔
收集整理的這篇文章主要介紹了
Visual C++ 中的ODBC编程
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
| Visual C++ 中的ODBC編程 |
| ODBC(Open?Database?Connectivity,開放式數據庫連接),是一種用來在相關或不相關的數據庫管理系統(DBMS)中存取數據的標準應用程序接口(API)。本文給出Windows?95?環境下用Visual?C++?進行ODBC?編程的具體方法及技巧。 ----?關鍵字:ODBC,Visual?C++,Windows?編程。 ----?一.概述 ----?ODBC?是一種使用SQL?的程序設計接口。使用ODBC?讓應用程序的編寫者避免了與數據源相聯的復雜性。這項技術目前已經得到了大多數DBMS?廠商們的廣泛支持。 ----?Microsoft?Developer?Studio?為大多數標準的數據庫格式提供了32?位ODBC?驅動器。這些標準數據格式包括有:SQL?Server、Access、Paradox、dBase、FoxPro、Excel、Oracle?以及Microsoft?Text。如果用戶希望使用其他數據格式,用戶需要相應的ODBC?驅動器及DBMS。 ----?用戶使用自己的DBMS?數據庫管理功能生成新的數據庫模式后,就可以使用ODBC?來登錄數據源。對用戶的應用程序來說,只要安裝有驅動程序,就能注冊很多不同的數據庫。登錄數據庫的具體操作參見有關ODBC?的聯機幫助。 ----?二.MFC?提供的ODBC?數據庫類 ----?Visual?C++?的MFC?基類庫定義了幾個數據庫類。在利用ODBC?編程時,經常要使用到CDatabase(?數據庫類),CRecordSet(?記錄集類)?和CRecordView(?可視記錄集類)。其中: ----?CDatabase?類對象提供了對數據源的連接,通過它你可以對數據源進行操作。 ----?CRecordSet?類對象提供了從數據源中提取出的記錄集。CRecordSet?對象通常用于兩種形式:動態行集(dynasets)和快照集(snapshots)。動態行集能保持與其他用戶所做的更改保持同步。快照集則是數據的一個靜態視圖。每一種形式在記錄集被打開時都提供一組記錄,所不同的是,當你在一個動態行集里滾動到一條記錄時,由其他用戶或是你應用程序中的其他記錄集對該記錄所做的更改會相應地顯示出來。 ----?CRecordView?類對象能以控制的形式顯示數據庫記錄。這個視圖是直接連到一個CRecordSet?對象的表視圖。 ----?三.應用ODBC?編程 ----?應用Visual?C++?的AppWizard?可以自動生成一個ODBC?應用程序框架。方法是:打開File?菜單的New?選項,選取Projects,填入工程名,選擇MFC?AppWizard?(exe),然后按AppWizard?的提示進行操作。當AppWizard?詢問是否包含數據庫支持時,如果你想讀寫數據庫,那么選定Database?view?with?file?support;而?閬敕夢適菘獾男畔⒍幌牖匭此齙母謀洌敲囪《―atabase?view?without?file?support?選項就比較合適了。選擇了數據庫支持之后Database?Source?按鈕會激活,選中它去調用Data?Options?對話框。在Database?Options?對話框中會顯示已向ODBC?注冊的數據庫資源,選定你所要操作的數據庫,如:Super_ES,單擊OK?后會出現Select?Database?Tables?對話框,其中列舉了你所選中的數據庫中包含的全部表,選擇你希望操作的表后,單擊OK。在選定了數據庫和數據表之后,你可以按照慣例繼續進行AppWizard?操作。 ----?特別需要指出的是:在生成的應用程序框架View?類(如:CSuper_ESView)中包含一個指向CSuper_ESSet?對象的指針m_pSet,該指針由AppWizard?建立,目的是在視表單和記錄集之間建立聯系,使得記錄集中的查詢結果能夠很容易地在視表單上顯示出來。有關m_pSet?的詳細用法可以參見Visual?C++?Online?Book。 ----?程序與數據語言建立聯系,使用CDatebase::OpenEx()?或CDatabase::Open()?函數來進行初始化。數據庫對象必須在你使用它構造一個記錄集對象之前被初始化。 ----?下面舉例說明在Visual?C++?環境中ODBC?的編程技巧: ----?1?.查詢記錄 ----?查詢記錄使用CRecordSet::Open()?和CRecordSet::Requery()?成員函數。在使用CRecordSet?類對象之前,必須使用CRecordSet::Open()?函數來獲得有效的記錄集。一旦已經使用過CRecordSet::Open()?函數,再次查詢時就可以應用CRecordSet::Requery()?函數。在調用CRecordSet::Open()?函數時,如果已經將一個已經打開的CDatabase?對象指針傳給CRecordSet?類對象的m_pDatabase?成員變量,則使用該數據庫對象建立ODBC?連接;否則如果m_pDatabase?為空指針,就新建一個CDatabase?類對象并使其與缺省的數據源相連,然后進行CRecordSet?類對象的初始化。缺省數據源由GetDefaultConnect()?函數獲得。你也可以提供你所需要的SQL?語句,并以它來調用CRecordSet::Open()?函數,例如: Super_ESSet.Open(AFX_DATABASE_USE_DEFAULT,strSQL); ----?如果沒有指定參數,程序則使用缺省的SQL?語句,即對在GetDefaultSQL()?函數中指定的SQL?語句進行操作: CString?CSuper_ESSet::GetDefaultSQL() {return?_T("[BasicData],[MainSize]");} ----?對于GetDefaultSQL()?函數返回的表名,對應的缺省操作是SELECT?語句,即: SELECT?*?FROM?BasicData,MainSize ----?查詢過程中也可以利用CRecordSet?的成員變量m_strFilter?和m_strSort?來執行條件查詢和結果排序。m_strFilter?為過濾字符串,存放著SQL?語句中WHERE?后的條件串;m_strSort?為排序字符串,存放著SQL?語句中ORDER?BY?后的字符串。如: Super_ESSet.m_strFilter="TYPE=電動機"; Super_ESSet.m_strSort="VOLTAGE"; Super_ESSet.Requery(); 對應的SQL語句為: SELECT?*?FROM?BasicData,MainSize? WHERE?TYPE=電動機 ORDER?BY?VOLTAGE ----?除了直接賦值給m_strFilter?以外,還可以使用參數化。利用參數化可以更直觀,更方便地完成條件查詢任務。使用參數化的步驟如下: ----?(1)?.聲明參變量: CString?p1; float?p2; ----?(2)?.在構造函數中初始化參變量 p1=_T(""); p2=0.0f; m_nParams=2; ----?(3)?.將參變量與對應列綁定 pFX-?>SetFieldType(CFieldExchange::param) RFX_Text(pFX,_T("P1"),p1); RFX_Single(pFX,_T("P2"),p2); ----?完成以上步驟之后就可以利用參變量進行條件查詢了: m_pSet-?>m_strFilter="TYPE=??AND?VOLTAGE=?"; m_pSet-?>p1="?電動機"; m_pSet-?>p2=60.0; m_pSet-?>Requery(); ----?參變量的值按綁定的順序替換查詢字串中的"?"?適配符。 ----?如果查詢的結果是多條記錄的話,可以用CRecordSet?類的函數Move(),MoveNext(),MovePrev(),MoveFirst()?和MoveLast()?來移動光標。 ----?2?.增加記錄 ----?增加記錄使用AddNew()?函數,要求數據庫必須是以允許增加的方式打開: m_pSet-?>AddNew();?//在表的末尾增加新記錄 m_pSet-?>SetFieldNull(&(m_pSet-?>m_type),?FALSE); m_pSet-?>m_type="?電動機"; ...?//輸入新的字段值 m_pSet-?>?Update();?//將新記錄存入數據庫 m_pSet-?>Requery();?//重建記錄集 ----?3?.刪除記錄 ----?直接使用Delete()?函數,并且在調用Delete()?函數之后不需調用Update()?函數: m_pSet-?>Delete(); if?(!m_pSet-?>IsEOF()) m_pSet-?>MoveNext(); else m_pSet-?>MoveLast(); ----?4?.修改記錄 ----?修改記錄使用Edit()?函數: m_pSet-?>Edit();?//修改當前記錄 m_pSet-?>m_type="發電機"; //修改當前記錄字段值 ... m_pSet-?>Update();?//將修改結果存入數據庫 m_pSet-?>Requery(); ----?5?.撤消操作 ----?如果用戶選擇了增加或者修改記錄后希望放棄當前操作,可以在調用Update()?函數之前調用: CRecordSet::Move(AFX_MOVE_REFRESH); ----?來撤消增加或修改模式,并恢復在增加或修改模式之前的當前記錄。其中的參數AFX_MOVE_REFRESH?的值為零。 ----?6?.數據庫連接的復用 ----?在CRecordSet?類中定義了一個成員變量m_pDatabase:? CDatabase*?m_pDatabase; ----?它是指向對象數據庫類的指針。如果在CRecordSet?類對象調用Open()?函數之前,將一個已經打開的CDatabase?類對象指針傳給m_pDatabase,就能共享相同的CDatabase?類對象。如: CDatabase?m_db; CRecordSet?m_set1,m_set2; m_db.Open(_T("Super_ES"));//建立ODBC連接 m_set1.m_pDatabase=&m_db; //m_set1復用m_db對象 m_set2.m_pDatabse=&m_db;? //?m_set2復用m_db對象 ----?7?.SQL?語句的直接執行 ----?雖然通過CRecordSet?類,我們可以完成大多數的查詢操作,而且在CRecordSet::Open()?函數中也可以提供SQL?語句,但是有的時候我們還想進行一些其他操作,例如建立新表,刪除表,建立新的字段等等,這時就需要使用到CDatabase?類的直接執行SQL?語句的機制。通過調用CDatabase::ExecuteSQL()?函數來完成SQL?語句的直接執行: BOOL?CDB::ExecuteSQLAndReportFailure(const?CString&?strSQL) { TRY { m_pdb-?>ExecuteSQL(strSQL);//直接執行SQL語句 } CATCH?(CDBException,e) { CString?strMsg; strMsg.LoadString(IDS_EXECUTE_SQL_FAILED); strMsg+=strSQL; return?FALSE; } END_CATCH? return?TRUE; } ----?應當指出的是,由于不同DBMS?提供的數據操作語句不盡相同,直接執行SQL?語句可能會破壞軟件的DBMS?無關性,因此在應用中應當慎用此類操作。 ----?8?.動態連接表 ----?表的動態連接可以利用在調用CRecordSet::Open()?函數時指定SQL?語句來實現。同一個記錄集對象只能訪問具有相同結構的表,否則查詢結果將無法與變量相對應。 void?CDB::ChangeTable() { if?(m_pSet-?>IsOpen())?m_pSet-?>Close(); switch?(m_id) { case?0: m_pSet-?>Open(AFX_DB_USE_DEFAULT_TYPE,? "SELECT?*?FROM?SLOT0");?//連接表SLOT0 m_id=1; break; case?1: m_pSet-?>Open(AFX_DB_USE_DEFAULT_TYPE,? "SELECT?*?FROM?SLOT1");?//連接表SLOT1 m_id=0; break; } } ----?9?.動態連接數據庫 ----?由于與數據庫的連接是通過CDatabase?類對象來實現的,所以我們可以通過賦與CRecordSet?類對象參數m_pDatabase?以連接不同數據庫的CDatabase?對象指針,就可以動態連接數據庫。 void?CDB::ChangeConnect() { CDatabase*?pdb=m_pSet-?>m_pDatabase; pdb-?>Close(); switch?(m_id) { case?0: if?(!pdb-?>Open(_T("Super_ES")))? //連接數據源Super_ES { AfxMessageBox("數據源Super_ES打開失敗," "請檢查相應的ODBC連接",?MB_OK|MB_ICONWARNING); exit(0); } m_id=1; break; case?1: if?(!pdb-?>Open(_T("Motor"))) //連接數據源Motor { AfxMessageBox("數據源Motor打開失敗," "請檢查相應的ODBC連接",?MB_OK|MB_ICONWARNING); exit(0); } m_id=0; break; } } ----?四.總結 ----?Visual?C++?中的ODBC?類庫可以幫助程序員完成絕大多數的數據庫操作。利用ODBC?技術使得程序員從具體的DBMS?中解脫出來,從而極大的減少了軟件開發的工作量,縮短開發周期,提高了效率和軟件的可靠性。本文總結的筆者從事軟件開發的一些經驗心得希望對從事ODBC?開發的工作者有所幫助。 |
總結
以上是生活随笔為你收集整理的Visual C++ 中的ODBC编程的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Android webview加载pdf
- 下一篇: 为什么大学普遍都教C/C++、Java,