西安外事學(xué)院工學(xué)院 文 欣
存取對(duì)象變量庫(kù)結(jié)構(gòu)作為一個(gè)功能較完備的Windows軟件開(kāi)發(fā)平臺(tái),Visual Basic專業(yè)版提供了對(duì)數(shù)據(jù)庫(kù)應(yīng)用的強(qiáng)大支持。尤其提供了使用數(shù)據(jù)控件和綁定控制項(xiàng),使用數(shù)據(jù)庫(kù)存取對(duì)象變量(Data Access Object Variable),直接調(diào)用ODBC 2.0 API接口函數(shù)等三種訪問(wèn)數(shù)據(jù)庫(kù)的方法。對(duì)其標(biāo)準(zhǔn)內(nèi)置的Ms Access數(shù)據(jù)庫(kù),它可以提供不弱于專業(yè)數(shù)據(jù)庫(kù)軟件的支持,可以進(jìn)行完整的數(shù)據(jù)庫(kù)維護(hù)、操作及其事務(wù)處理。在VB中,將非Access數(shù)據(jù)庫(kù)稱為外來(lái)數(shù)據(jù)庫(kù)。對(duì)于FoxPro、dBASE、Paradox等外來(lái)數(shù)據(jù)庫(kù)。雖然借助VB的Data Manager能夠?qū)@些數(shù)據(jù)庫(kù)進(jìn)行NEW、OPEN、DESIGN、DELETE等操作,但在應(yīng)用程序的運(yùn)行狀態(tài)中并不能從底層真正實(shí)現(xiàn)這些功能。本文從使用數(shù)據(jù)庫(kù)存取對(duì)象變量的方法出發(fā),實(shí)現(xiàn)了非Access格式數(shù)據(jù)庫(kù)(以FoxPro數(shù)據(jù)庫(kù)為例)的建新庫(kù)、拷貝數(shù)據(jù)庫(kù)結(jié)構(gòu)、動(dòng)態(tài)調(diào)入等操作,闡述了從編程技巧上彌補(bǔ)VB對(duì)這些外來(lái)數(shù)據(jù)庫(kù)支持不足的可行性。
VB數(shù)據(jù)庫(kù)的核心結(jié)構(gòu)是所謂的MicroSoft JET數(shù)據(jù)庫(kù)引擎,JET引擎的作用就像是一塊“面板”,在其上可以插入多種ISAM(Indexed Sequential Access Method,即索引順序存取方法)數(shù)據(jù)驅(qū)動(dòng)程序。
VB專業(yè)版中提供了FoxPro、dBASE(或Xbase)、Paradox、Btrieve等數(shù)據(jù)庫(kù)的ISAM驅(qū)動(dòng)程序,這就使得VB能支持這些數(shù)據(jù)庫(kù)格式。另外,其他的許多兼容ISAM的驅(qū)動(dòng)程序也可以通過(guò)從廠商的售后服務(wù)得到。因而從理論上說(shuō),VB能支持所有兼容ISAM的數(shù)據(jù)庫(kù)格式(前提是只需獲得這些數(shù)據(jù)庫(kù)的ISAM驅(qū)動(dòng)接口程序)。
由上可見(jiàn),Ms JET引擎實(shí)質(zhì)上提供了:一個(gè)符合ANSI標(biāo)準(zhǔn)的語(yǔ)法分析器;為查詢結(jié)果集的使用而提供的內(nèi)存管理功能;同所支持的數(shù)據(jù)庫(kù)的外部接口;為應(yīng)用代碼提供的內(nèi)部接口。實(shí)際上,在VB中從一種數(shù)據(jù)庫(kù)類型轉(zhuǎn)化為另一種數(shù)據(jù)庫(kù)類型幾乎不需要或只需要很少的代碼修改。而且,盡管dBASE、Paradox本身的DDL(Data Definition Language,即數(shù)據(jù)定義語(yǔ)言)和DML(Data Manipulation Language,即數(shù)據(jù)操縱語(yǔ)言)是非結(jié)構(gòu)化查詢的,但它們?nèi)匀豢梢允褂肰B的SQL語(yǔ)句和JET引擎來(lái)操縱。
從VB的程序代碼的角度來(lái)看,ODBC,ISAM驅(qū)動(dòng)程序以及Ms Access數(shù)據(jù)庫(kù)的整個(gè)外部結(jié)構(gòu)夠可以統(tǒng)一為一個(gè)一致的編程接口。也即是說(shuō),提供給VB應(yīng)用程序員的記錄集對(duì)象視圖同所使用的數(shù)據(jù)庫(kù)格式及類型是相互獨(dú)立的。即對(duì)FoxPro等數(shù)據(jù)庫(kù)仍然可以使用眾多的數(shù)據(jù)庫(kù)存取對(duì)象變量,這就為非Access數(shù)據(jù)庫(kù)的訪問(wèn)提供了最重要的方法。
如果在VB的程序中使用了數(shù)據(jù)庫(kù)的操作,將應(yīng)用程序生成EXE文件或打包生成安裝程序后,則必須提供一個(gè)配置(.INI)文件,在INI文件中可以對(duì)不同類型的數(shù)據(jù)庫(kù)進(jìn)行設(shè)置。通常情況下,INI文件的文件名和應(yīng)用程序的名稱相同,所以如果沒(méi)有指明,VB的程序會(huì)在Windows子目錄中去找和應(yīng)用程序同名的INI文件??梢允褂肰B中的SetDataAccessOptions語(yǔ)句來(lái)設(shè)置INI文件。
SetDataAccessOptions語(yǔ)句的用法如下:
SetDataAccessOptions 1,IniFile-Name其中IniFileName參數(shù)指明的是INI文件的帶路徑的文件名。值得注意的是,當(dāng)應(yīng)用程序找不到這個(gè)INI文件時(shí),或在調(diào)用OpenDataBase函數(shù)時(shí)對(duì)其Connect參數(shù)值沒(méi)有設(shè)定為VB規(guī)定的標(biāo)準(zhǔn)值,如對(duì)FoxPro 2.5格式設(shè)定為了"FoxPro;"(應(yīng)為"FoxPro 2.5;"),或者沒(méi)有安裝相應(yīng)的ISAM驅(qū)動(dòng)程序,則此時(shí)VB會(huì)顯示一條錯(cuò)誤信息"Not Found Installable ISAM"。通常,INI文件在應(yīng)用程序分發(fā)出去以前已經(jīng)生成,或者在安裝時(shí)動(dòng)態(tài)生成,也可以在應(yīng)用程序中自己生成。通常這種INI文件中有"[Options]"、"[ISAM]"、"[Installed ISAMs]"、"[FoxPro ISAM]"、"[dBASE ISAM]"、"[Paradox ISAM]"等設(shè)置段,對(duì)于一個(gè)完整的應(yīng)用程序則還應(yīng)有一個(gè)屬于應(yīng)用程序自己的設(shè)置段如"[MyDB]"??稍谄渲性O(shè)置DataType、Server、DataBase、OpenOnStartup、DisplaySQL、QueryTimeOut等較為重要的數(shù)據(jù)庫(kù)參數(shù),并以此限定應(yīng)用程序一般的運(yùn)行環(huán)境。Windows API接口函數(shù)在Kernel.exe動(dòng)態(tài)鏈接庫(kù)中提供了一個(gè)OSWritePrivateProfileString函數(shù),此函數(shù)能按Windows下配置文件(.INI)的書(shū)寫(xiě)格式寫(xiě)入信息。
設(shè)此應(yīng)用程序的配置文件為MyDB.INI,則具體過(guò)程如下:Funtion GetINIString$(Byval Fname$,Byval szItem$,Byval szDeFault$)'此自定義子函數(shù)實(shí)現(xiàn)INI文件內(nèi)設(shè)置段內(nèi)參數(shù)的讀取Dim Tmp As String,x As Integer Tmp=String(2048,32)x=OSGetPrivat eProfileString(Fname$,szItem$,szDefault$,Tmp,Len(Tmp),"MyDB.INI")GetINIString=Mid$(Tmp,1,x)EndFunction以下這些函數(shù)的聲明可寫(xiě)在模塊文件內(nèi),且每個(gè)函數(shù)的聲明必須在一行內(nèi)Declare Function OSGetPrivateProfileString% Lib"Kerne l"Alias"GetPrivateProfileString"(By Val AppName$,ByVal KeyName$,ByVal keydefault$,ByVal ReturnString$,ByVal NumBytes As Integer,ByVal FileName$)Declare Function OSWritePrivateProfileString% Lib"Kern el"Alias"WritePrivateProfileString"(B yVal AppName$,ByVal KeyName$,ByVal keydefault$,ByVal FileName$)Declare Function OSGetWindowsDirectory% Lib"K ernel"Alias"GetWindowsDirectory"(ByV al a$,ByVal b%)Sub Form1_Load( )Dim st As String Dim x As Integer Dim tmp As String tmp=String$(255,32)'
INI文件內(nèi)為各種數(shù)據(jù)庫(kù)格式指明已安裝的相應(yīng)ISAM驅(qū)動(dòng)程序x=OSWrit ePrivateProfileString(“Installab le ISAMS”,"Paradox 3.X","PDX110.DLL","MyDB.INI")x=OSWritePrivateP rofileString("Installable ISAMS","dBASE III","XBS110.DLL","MyDB.INI")x=OSWritePrivateProfileString("Installable ISAMS","dBASE IV","XBS110.DLL","MyDB.INI")x=OSWrite PrivateProfileString("Installable ISAMS","FoxPro 2.0","XBS110.DLL","MyDB.INI" )x=OSWritePrivateProfile String("Installable ISAMS","FoxPro 2.5","XBS110.DLL","MyDB.INI")x=O SWritePrivateProfileString("Instal lable ISAMS","Btrieve","BTRV110.DLL","MyDB.INI")x=OSWritePrivatePro fileString("dBase ISAM","Deleted","On","MyDB.INI")’指明INI文件的位置x=OSGetWindowsDirectory(tmp,255)st=Mid$(tmp,1,x)SetDataAccessOption 1,s t+"m y d b.i n i"‘獲得I N I文件一些參數(shù)g w M a x G r i d R o w s=Val(GetINIString("MyDB.INI","MaxRows","250")) glQueryTimeout=Val(GetINIString("MyDB.INI","QueryTimeout","5")) glLoginTimeout=Val(GetINIString("MyDB.INI","LoginTimeout","20" ))End Sub
在VB專業(yè)版數(shù)據(jù)庫(kù)編程的三種方法中,第二種,使用數(shù)據(jù)庫(kù)存取對(duì)象變量(DAO)的方法最具有功能強(qiáng)大、靈活的特點(diǎn)。它能夠在程序中存取ODBC 2.0的管理函數(shù);可以控制多種記錄集類型:Dynaset,Snapshot及Table記錄集合對(duì)象;可以存儲(chǔ)過(guò)程和查詢動(dòng)作;可以存取數(shù)據(jù)庫(kù)集合對(duì)象,例如TableDefs,F(xiàn)ields,Indexes及QueryDefs;具有真正的事物處理能力。因而,這種方法對(duì)數(shù)據(jù)庫(kù)處理的大多數(shù)情況都非常適用。
由于VB中的記錄集對(duì)象與所使用的數(shù)據(jù)庫(kù)格式及類型是相互獨(dú)立的,所以在非Access數(shù)據(jù)庫(kù)中也可以使用數(shù)據(jù)庫(kù)存取對(duì)象變量的方法。因而對(duì)FoxPro等外來(lái)數(shù)據(jù)庫(kù)而言,使用數(shù)據(jù)庫(kù)存取對(duì)象變量的方法同樣也是一種最佳的選擇。
非Access數(shù)據(jù)庫(kù)的新建及庫(kù)結(jié)構(gòu)的修改VB專業(yè)版中的數(shù)據(jù)庫(kù)存取對(duì)象變量可以分為兩類,一類用于數(shù)據(jù)庫(kù)結(jié)構(gòu)的維護(hù)和管理,另一類用于數(shù)據(jù)的存取。其中表示數(shù)據(jù)庫(kù)結(jié)構(gòu)時(shí)可以使用下面的對(duì)象:
DataBase、TableDef、Field、Index,以及三個(gè)集合(Collection):TableDefs、Fields和Indexes。每一個(gè)集合都是由若干個(gè)對(duì)象組成的,這些數(shù)據(jù)對(duì)象的集合可以完全看作是一個(gè)數(shù)組,并按數(shù)組的方法來(lái)調(diào)用。對(duì)于非Access數(shù)據(jù)庫(kù),大部分都是對(duì)應(yīng)于一個(gè)目錄,所以可以使用VB的MkDir語(yǔ)句先生成一個(gè)目錄,亦即新建一個(gè)數(shù)據(jù)庫(kù)。而每一個(gè)非Access數(shù)據(jù)庫(kù)文件可看作是此目錄下的一個(gè)數(shù)據(jù)表(Table),但實(shí)際上它們是互相獨(dú)立的。
下面是新建一個(gè)FoxPro 2.5格式數(shù)據(jù)庫(kù)的程序?qū)嵗?/p>
Sub CreateNew( )Dim Db1 As database,Td As TableDefs Dim T1 As New Tabledef,F(xiàn)1 As New Field,F(xiàn)2 As New Field,F(xiàn)3 As New Field Dim Ix1 As New Index Dim Path As String Const DB_TEXT=10,DB_INTEGER=3 ChDir""Path$=InputBox(“請(qǐng)輸入新路徑名:”,“輸入對(duì)話框”)MkDir Path$‘新建一個(gè)子目錄Set Db1=OpenDatabase(Path$,True,F(xiàn)alse,"FoxPro 2.5;")Set Td = Db1.TableDefs T1.Name="MyDB"‘新建一個(gè)數(shù)據(jù)表,數(shù)據(jù)表名為MyDB F1.Name="Name",F(xiàn)1.Type=DB_TEXT,F(xiàn)1.Size=20 F2.Name="Class",F(xiàn)2.Type=DB_TEXT,F(xiàn)2.Size=20 F3.Name="Grade",F(xiàn)3.Type=DB_INTEGER T1.Fields.Append F1‘向數(shù)據(jù)表中添加這些字段T1.Fields.Append F2。
[1]明日科技.Visual Basic開(kāi)發(fā)經(jīng)驗(yàn)技巧寶典[M].人民郵電出版社,2007,9.
[2]邱李華,等.Visual Basic程序設(shè)計(jì)教程[M].機(jī)械工業(yè)出版社,2007,7.
[3]李淑華.VB程序設(shè)計(jì)及應(yīng)用[M].高等教育出版社,2008,9.
[4]張勇.Visual Basic課程設(shè)計(jì)案例精編[M].中國(guó)水利水電出版社,2010,3.