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