VisualC++數(shù)據(jù)庫連接論文

時間:2022-03-20 02:12:00

導(dǎo)語:VisualC++數(shù)據(jù)庫連接論文一文來源于網(wǎng)友上傳,不代表本站觀點,若需要原創(chuàng)文章可咨詢客服老師,歡迎參考。

VisualC++數(shù)據(jù)庫連接論文

一、開放數(shù)據(jù)庫連接

ODBC(OpenDataBaseConnectivity,開放數(shù)據(jù)庫連接)是微軟開放服務(wù)結(jié)構(gòu)中有關(guān)數(shù)據(jù)庫的一個組成部分。它建立了一組規(guī)范,并提供了一組應(yīng)用程序調(diào)用接口。用這樣一組接口建立的應(yīng)用程序,對數(shù)據(jù)庫的操作不依賴于任何數(shù)據(jù)庫管理系統(tǒng),不直接與任何DBMS打交道,由此可實現(xiàn)應(yīng)用程序?qū)Σ煌珼BMS的共享論文。數(shù)據(jù)庫操作的“數(shù)據(jù)源”對應(yīng)用程序是透明的,所有的數(shù)據(jù)庫操作由對應(yīng)DBMS的ODBC驅(qū)動程序(ODBCDriver)完成。有了ODBC驅(qū)動程序,數(shù)據(jù)源就變得十分廣泛,它可以是本機(jī)的某種數(shù)據(jù)庫格式的文件(如本機(jī)DOS目錄下的Access文

件*.mdb),也可以是遠(yuǎn)程數(shù)據(jù)庫文件(如MicrosoftSQLServer);它可以是已知的某種DBMS格式,也可以是一種全新的數(shù)據(jù)庫格式??傊?它取決于提供了什么數(shù)據(jù)庫類型的驅(qū)動程序。

visualc++中的ODBC主要是實現(xiàn)基于Windows的關(guān)系數(shù)據(jù)庫的應(yīng)用的共享。

二、ODBC管理器

在ODBC中,數(shù)據(jù)源是一個重要的概念,它是數(shù)據(jù)庫位置和數(shù)據(jù)庫類型等連接信息的總和。數(shù)據(jù)源在使用前必須通過ODBC管理器(Administrator)進(jìn)行登錄。在登錄數(shù)據(jù)源時,要搞清數(shù)據(jù)源名(Datasourcename)、數(shù)據(jù)庫文件名(Databasename)和數(shù)據(jù)表格名(Tablename)這三者的概念和相互關(guān)系:數(shù)據(jù)源實際是一種數(shù)據(jù)連接的抽象,數(shù)據(jù)源名是登錄時賦予的“連接”的名稱,以供應(yīng)用程序使用,至于該數(shù)據(jù)源下連接的是哪一個數(shù)據(jù)庫,則由數(shù)據(jù)庫文件名指出(如Access2.0forMSOffics中的.mdb文件);一個數(shù)據(jù)庫文件中可以包括若干個數(shù)據(jù)表格(table)和其他。在關(guān)系@@09A05900.GIF;圖1ODBC層次關(guān)系圖數(shù)據(jù)庫中,數(shù)據(jù)是以二維表格的方式存在于數(shù)據(jù)庫@@文件中,應(yīng)用程序最終的操作目標(biāo)即是這些表格中的行(row記錄)和列(columns字段)數(shù)據(jù)。對于foxprow數(shù)據(jù)源,數(shù)據(jù)庫文件名是“路徑名”,而該路徑下的所有數(shù)據(jù)文件(*.dbf)都屬于該“數(shù)據(jù)庫文件”名下的數(shù)據(jù)表格(table)。

ODBC管理器被裝在ControlPanel里(ODBCINST.CPL)。通過該工具可以增添、修改或刪除數(shù)據(jù)源,也用來增添、刪除ODBC驅(qū)動程序,ODBC管理器把數(shù)據(jù)源和它們的連接信息保存在ODBC.INI、ODBCINST.INI和ODBCISAM.INI中。當(dāng)需要共享應(yīng)用程序時,只需按新的數(shù)據(jù)文件的類型和位置重新登錄即可。

三、ODBC應(yīng)用程序接口

ODBCAPI是一組標(biāo)準(zhǔn)的ODBC函數(shù)庫,除了一般的數(shù)據(jù)庫操作函數(shù)外,還包括一組函數(shù)(如SQLExec或SQLExecdirect)能夠內(nèi)嵌標(biāo)準(zhǔn)SQL查詢語句。SQL(StructuredQueryLanguage結(jié)構(gòu)化查詢語言)是一種存取關(guān)系型數(shù)據(jù)庫的標(biāo)準(zhǔn)語言,能夠定義、查詢、修改和控制數(shù)據(jù),簡單的語句能夠作用于整個數(shù)據(jù)表格,具有很強(qiáng)的功能。

同Windows3.1SDK中API類似,ODBCAPI也是基于句柄(handle)進(jìn)行操作的。API函數(shù)按功能可分為以下幾類:

·數(shù)據(jù)源連接函數(shù),設(shè)置/獲取有關(guān)信息的函數(shù);

·準(zhǔn)備/提交執(zhí)行SQL查詢語句的函數(shù)和獲得數(shù)據(jù)的函數(shù);

·終止函數(shù)和異常處理函數(shù)。

上述函數(shù)的順序也表示了進(jìn)行數(shù)據(jù)庫操作的一般順序。兩個需要特別說明,一是數(shù)據(jù)類型問題:數(shù)據(jù)源中的數(shù)據(jù)所具有的數(shù)據(jù)類型稱為SQL數(shù)據(jù)類型,這些數(shù)據(jù)類型在其數(shù)據(jù)源中可能比較特殊,不一定和ODBCSQL數(shù)據(jù)類型存儲方式一致,驅(qū)動程序把這些數(shù)據(jù)類型同ODBCSQL數(shù)據(jù)類型進(jìn)行相互轉(zhuǎn)換,每一個ODBCSQL數(shù)據(jù)類型都相當(dāng)于一個ODBCC語言數(shù)據(jù)類型;二是函數(shù)的調(diào)用級別問題,并不是每一個ODBC驅(qū)動程序都支持所有的ODBCAPI函數(shù)調(diào)用,在應(yīng)用程序中,可以調(diào)用有關(guān)函數(shù)獲取驅(qū)動程序以支持層次方面的信息。

四、ODBC編程

在VisualC++中,MFC(MicrosoftFoundationClass基本類庫)是經(jīng)過對Windows應(yīng)用程序中各個部件進(jìn)行類的抽象而建立的一組預(yù)定義的類,如窗口基類(CWnd)、各種窗口派生類等等,這些類在應(yīng)用程序中可直接使用,不需要重新定義。在MFC中,也為ODBC預(yù)定義了幾個類,其中主要的是數(shù)據(jù)庫類(CDatabase)和記錄集合類(CRecoredset)。這兩個類既有聯(lián)系又有區(qū)別,在應(yīng)用程序中,可以分別使用,也可以同時使用,每一類也可以同時存在多個對象。CDatabase的每一個對象代表了一個數(shù)據(jù)源的連接,CRecordset的每一個對象代表了從一

個數(shù)據(jù)表中按預(yù)定的查詢條件獲得的記錄的集合,一般說來,前者適宜于對數(shù)據(jù)源下的某個數(shù)據(jù)表格進(jìn)行整體操作,后者用于對所選的記錄集合進(jìn)行處理。

同Windows類與SDKAPI函數(shù)的關(guān)系一樣,CDatabase類與ODBCAPI函數(shù)也有類似的關(guān)系,但CDatabase類中并不包含所有的ODBCAPI函數(shù),大部分操作功能仍須直接調(diào)用ODBCAPI函數(shù),如目錄功能函數(shù),用于獲得數(shù)據(jù)源下的數(shù)據(jù)表格信息,如表格名,字段名等。

在應(yīng)用編程時,一般使用CDatabase和CRecordset的派生類。假設(shè)派生類分別為CUserdb和CUserset,而在應(yīng)用類CUserClass中,使用了一個CUserdb對象(m-db)和一個Cuserset對象(m-recset),圖2給出了用戶應(yīng)用類與ODBC類的相互關(guān)系示意圖。

@@09A05901.GIF;圖2CDatabaseCRecordset類與應(yīng)用類及數(shù)據(jù)源關(guān)系圖@@

1.m-db連接數(shù)據(jù)源

m-db在完成定義構(gòu)造后,要調(diào)用CDatabase的打開(Open)函數(shù)以進(jìn)行數(shù)據(jù)源的實際連接:

m-db.Open(lpszDSN,bExclusive,bReadOnly,lpszConnect);

打開函數(shù)需要輸入四個參數(shù)。lpszDSN:要連接的數(shù)據(jù)源的名字,如果lpszDSN=NULL且lpszConnect中也沒有指明數(shù)據(jù)源名,則該調(diào)用會自動出現(xiàn)一個對話框列出所有可用的數(shù)據(jù)源(名),讓用戶選擇。bExclusive:只支持“假”(False)值,表示為共享(share)方式連接。因此,應(yīng)用程序在運行前,一定要裝入share.exe或在Windows的system.ini中裝入vshare.386。ReadOnly:指明數(shù)據(jù)源操作方式是“只讀”還是可以修改。lpszConnect:指明連接字符串,包括數(shù)據(jù)源名、用戶標(biāo)識碼、口令等信息。該字符串必須以“ODBC;”開頭,表示該連接是與一個ODBC數(shù)據(jù)源的連接(考慮以后版本支持非ODBC數(shù)據(jù)源)。

m-db打開后,其指針可以傳給m-recset作為其數(shù)據(jù)源。m-db關(guān)閉后,將關(guān)閉所有CRecordset對它的連接,m-db也可以重新打開。

2.m-db操作數(shù)據(jù)

數(shù)據(jù)源打開后,即可對數(shù)據(jù)庫文件中的數(shù)據(jù)表格進(jìn)行操作,操作以調(diào)用SQL語句方式進(jìn)行,可直接通過ODBCAPI函數(shù),或者CDatabase類成員函數(shù)ExecuteSQL。數(shù)據(jù)表名在SQL語句中指定,如下語句則在所在的數(shù)據(jù)源中的clerk表中插入一個記錄,記錄的name字段值為"chen"。

m-db.ExecuteSQL("insertintoclerk(name)value(''''chen'''')");3.m-recset連接數(shù)據(jù)m-recset在構(gòu)造時,可傳入一個CDatabase對象指針,作為m-recset的數(shù)據(jù)源,當(dāng)為NULL時,必須重載CRecordset的函數(shù)GetDefaultConnect,以提供數(shù)據(jù)源連接字符串(相當(dāng)于m-db.Open中的lpszConnect)。如下則表示連接名為COMPANY的數(shù)據(jù)源(當(dāng)傳入了合法的CDatabase對象指針時,該函數(shù)將不被調(diào)用)。

CStringCUserset::GetDefaultConnect()

{

return"ODBC;DSN=COMPANY;";

}4.m-recset選取記錄和字段

m-recset在調(diào)用打開函數(shù)時,即獲得了符合條件的一組記錄,條件語句在Open函數(shù)中的lpszSQL中給出,如果lpszSQL為NULL,則必須重載CRecordset的函數(shù)以提供該語句。該語句是一個SELECT語句,帶或不帶where和orderby子句(如果不帶,where和Orderby的條件也可在CRecordset的兩個預(yù)定義成員變量m-strFilter和m-strSort中給出)。lpszSQL也可以只是一個數(shù)據(jù)表名(table-name),也可以是對內(nèi)嵌在數(shù)據(jù)庫文件中的查詢程序的調(diào)用語句。所選擇的一系列字段名,在成員函數(shù)DoFieldExchange中由一系列RFX-函數(shù)指定。RFX-(RecordFieldExchange)函數(shù),使字段和成員變量一一建立類型對應(yīng)關(guān)系。另外,m-strFilter中也可以帶變量參數(shù)(用"?"表示,如"fieldl>=?ANDfield2<=?"),參數(shù)與成員變量的對應(yīng)關(guān)系也在DoFieldExchange中由RFX-函數(shù)指定(串中的"?"將被參數(shù)變量值逐一替換)。

voidCUserset::DoFieldExchange(CFieldExchange*pFX)

{

pFX->SetFieldType(CFieldExchange::outputColumn);

/*以下為字段連接*/

RFX-???(pFX,"field1",m-var1);

RFX-???(pFX,"field2",m-var2);

...

RFX-???(pFX,"fieldn",m-varn);

pFX->SetFieldType(CFieldExchange::param);

/*以下為參數(shù)連接*/

RFX-???(pFX,field1,m-param1);

RFX-???(pFX,field2,m-param2);

...

}其中,???為ODBCSQL數(shù)據(jù)類型名,如RFX-Double,RFX-Text等。

綜合上述,選取記錄和字段實際是由下列語句完成:

SELECTrfx-field-listFROMtable-name[WHEREm-strFilter][ORDERBYm-strSort]

字段變量和參數(shù)變量的個數(shù)一定要在調(diào)用打開函數(shù)前(如構(gòu)造函數(shù)中)準(zhǔn)確地賦值給成員變量m-nFields和m-nParams。m-recset在打開后的任何時候調(diào)用Requery()函數(shù),將根據(jù)新的查詢條件(例如修改了參數(shù)變量值)重新選取記錄。

5.m-recset操作數(shù)據(jù)

記錄集合生成后,其當(dāng)前記錄的各字段值被保存在前述的各字段變量中,如果調(diào)用CRecordset的滾動(scroll)函數(shù),如MoveFirst(),MoveNext(),MovePrev(),MoveLast()等,字段變量的值將自動跟隨“當(dāng)前”記錄的位置的變化而變化。IsBOF(),IsEOF()用于判別是否移動到記錄的頭或尾。

數(shù)據(jù)操作主要包括刪除(Delete),添加(AddNew)和更改(Edit),一般流程為:

if(m-recset.CanUpdate())/*是否允許修改*/

{

if(m-db.CanTransact())/*是否支持“批”處理*/

{

m-db.BeginTrans();

m-recset.AddNew();

/*修改字段變量值*/

...

m-recset.Update();

m-mitTrans();

if(catcherror)

m-db.RollBack();

}

}

對于AddNew和Edit,修改字段變量后一定要調(diào)用函數(shù)Update(),否則更新將丟失,而Delete操作則不必進(jìn)行字段值修改和調(diào)用Update()。

上述的CDatabase的四個函數(shù)是ODBC為保證數(shù)據(jù)操作的可靠性而提供的“批”處理函數(shù),即在BeginTrans和CommitTrans之間的數(shù)據(jù)修改如果出現(xiàn)任何異常,可通過函數(shù)RoolBack來恢復(fù)所做的修改。

在多用戶系統(tǒng)使用時,每一個數(shù)據(jù)源可以被多個用戶的多個任務(wù)連接,不同的任務(wù)可同時修改相同的數(shù)據(jù)源。ODBC提供了兩種數(shù)據(jù)表更新的同步機(jī)制(在m-recset.Open函數(shù)中指定),“靜態(tài)”的(snapshot)和動態(tài)的(dynaset)。前者是一組靜態(tài)的記錄集合,當(dāng)建立后不會改變,除了反應(yīng)自己的添加/刪除外,不反應(yīng)別的用戶的修改,除非調(diào)用了Requery重新建立。后者是一組動態(tài)的記錄集合,自己或別的用戶所作的修改隨時反應(yīng)到集合中來(當(dāng)然也可用Requery重建),以保持記錄與數(shù)據(jù)源的同步。在應(yīng)用中,應(yīng)根據(jù)需要確定使用哪一種方式。

五、結(jié)束語

從以上討論可以看出,ODBC應(yīng)用接口十分簡便!再加上VisualC++中的AppWizard和ClassWizard自動生成框架代碼功能,連接一個數(shù)據(jù)源,生成一個CRecordset對象,就更快捷了。

應(yīng)用程序只需關(guān)心數(shù)據(jù)的處理而不必費心數(shù)據(jù)的存取,另外,另一個與ODBC有關(guān)的類CRecordView,是一個窗口類CWnd的派生類,建立在CRecordset上,可直接構(gòu)造數(shù)據(jù)庫記錄顯示窗口,某些情況下也不妨一用。