在VB中兼容非ACCESS数据库的技巧


  摘要:

  本文从VB数据库体系 构造的角度 起程, 联合一个具体实例, 阐述了在VB中兼容非ACCESS 格局数据库的具体 步骤和技巧 。
要害词:VB、非ACCESS数据库、数据存取对象

  一个 完全的数据库治理系统(DBMS)应是能兼容市面上各种较 风行数据 格局的系统,它 充足考量了不同消费者的实际要求 。鉴于当前市面上有多种数据库 格局(如Foxpro、DBase、Paradox等) 风行, 因此在VB数据库 利用程序中兼容非Access数据库就显得尤为主要了 。
  作为一种 风行的开发平台,VB提供了 壮大的数据库 性能 。主要有以下三种:数据控件法: 使用数据存取对象(Data Access Object )法;直接调用ODBC 2.0 API接口函数法 。其中调用数据存取对象的 步骤 绝对其它两种 步骤 存在容易灵便、 性能 壮大的突出 长处 。本文即从调用数据库存取对象的 步骤 起程,实现了非Access 格局数据库(以FoxPro数据库为例)的建新库、拷贝数据库 构造、动态调入等操作, 阐述了从编程技巧上 补偿VB对这些外来数据库 支撑缺乏的可行性 。

  一、VB数据库的体系 构造
  
VB数据库的核心 构造是所谓的MicroSoft JET数据库引擎,它为VB与数据库的接口提供了 根本的 步骤和 目的 。JET引擎被Visual Basic、Microsoft Access和其它Microsoft产品所共享 。 因此在VB中Access数据库 格局是一种 标准的内置 格局,所有的非Access数据库都被称为外来数据库 。
  JET引擎的作用就像是一块“面板”,在其上 可以插入多种索引顺序存取 步骤(即ISAM)数据驱动程序 。这便是VB对非Access数据库 存在 丰硕 支撑的真正缘由 。VB专业版中提供了FoxPro、dBASE(或Xbase)、Paradox、Btrieve等数据库的ISAM驱动程序,这就使得VB能 支撑这些数据库 格局 。另外, 其余的许多兼容ISAM的驱动程序也 可以通过从厂商的售后服务得到 。 因此从 实际上说,VB能 支撑所有兼容ISAM的数据库 格局(前提是 惟独 获得这些数据库的ISAM驱动接口程序) 。

  二、 使用非Access数据库时的参数设置及配置文件的参数读取
  
值得 留神的是,大多数的程序员都不 重视数据库配置文件的 使用,殊不知这是极为主要的 。
  假如在VB的程序中 使用了数据库的操作,将 利用程序生成EXE文件或打包生成安装程序后,则必须提供一个数据库配置(.INI)文件,在INI文件中 可以对不同类型的数据库进行设置 。假如找不到这个INI文件,将会招致不能 拜访数据库 。通常状况下,INI文件的文件名和 利用程序的名称 雷同,所以假如没有指明,VB的程序会在Windows子目录中去找和 利用程序同名的INI文件 。 可以 使用VB中的SetDataAccessOptions语句来设置INI文件 。
SetDataAccessOptions语句的用法如下:
SetDataAccessOptions 1,IniFileName
其中IniFileName参数指明的是INI文件的 引路径的文件名 。
  值得 留神的是,当 利用程序找不到这个INI文件时,或在调用OpenDataBase函数时对其Connect参数值没有设定为VB规定的 标准值,如对FoxPro 2.5 格局设定为了“FoxPro;”(应为“FoxPro 2.5;”),或者没有安装相应的ISAM驱动程序,则此时VB会显示一条 舛误信息“Not Found Installable ISAM” 。
通常,INI文件在 利用程序 散发出去以往已经生成,或者在安装时动态生成,也 可以在 利用程序中自己生成 。通常这种INI文件中有“[Options]”、“[ISAM]”、“[Installed ISAMs]”、“[FoxPro ISAM]”、“[dBASE ISAM]”、“[Paradox ISAM]”等设置段,关于一个 完全的 利用程序则还应有一个属于 利用程序自己的设置段如“[MyDB]” 。可在其中设置DataType、Server、DataBase、OpenOnStartup、DisplaySQL、QueryTimeOut等较为主要的数据库参数,并以此限定 利用程序普通的运行环境 。
Windows API接口函数在Win95系统提供的动态链接库中提供了一个OSWritePrivateProfileString函数,此函数能按Windows下配置文件(.INI)的书写 格局写入信息 。
在通常状况下, 利用程序还需求在运行时读取配置文件内 有关项的参数 。 比方PageTimeOut(页加锁超时时限)、MaxBufferSize(缓冲区大小)、LockRetry(加锁失败时重试次数)等参数,通过对这些参数的读取对 利用程序运行环境的设定、潜在 舛误的 拿获等均会有很大的改善 。
设此 利用程序的数据库配置文件为MyDB.INI,则具体过程如下:
Funtion GetINIString$( Byval Fname$,Byval szItem$,Byval szDeFault$ )
’此自定义子函数实现INI文件内设置段内参数的读取
Dim Tmp As String, x As Integer
Tmp = String( 2048,32 )
x = OSGetPrivateProfileString( Fname$,szItem$,szDefault$,Tmp,Len(Tmp),“MyDB.INI”)
GetINIString = Mid$( Tmp,1,x )
End Function
通过此函数就能实现对各种数据库 格局的读取 。
  三、调用数据存取对象对非Access数据库编程的 步骤及其实例
  
VB专业版中 使用数据库存取对象变量(DAO)的 步骤最 存在 性能 壮大、编程灵便的特色 。它 可以在程序中存取ODBC 2.0的治理函数; 可以控制多种记录集类型:Dynaset,Snapshot及Table记录 集中对象; 可以存储过程和 查问动作; 可以存取数据库 集中对象,例如TableDefs,Fields,Indexes及QueryDefs; 存在真正的事物 解决 威力 。这种 步骤对数据库 解决的大多数状况都十分 实用 。
从VB的程序代码的角度来看,提供应VB程序员的记录集对象(RecordSet)同所 使用的数据库 格局及类型是 彼此独立的 。即对FoxPro等数据库 依旧 可以 使用众多的数据库存取对象变量,这就为非Access数据库的 拜访提供了最主要的前提和 步骤 。
在VB中从一种数据库类型转化为另一种数据库类型 几乎不需求或 惟独求很少的代码 批改 。而且, 只管dBASE、Paradox 本身的DDL(Data Definition Language,即数据定义语言)和DML(Data Manipulation Language,即数据控制语言)是非 构造化 查问的,但它们 依旧 可以 使用VB的SQL语句和JET引擎来控制 。
因此对FoxPro等非Access数据库而言,调用数据库存取对象的 步骤同样也是一种最佳的 取舍 。


  (一)非Access数据库的新建及库 构造的 批改
  VB专业版中的数据库存取对象变量 可以分为两类,一类用于数据库 构造的 保护和治理,另一类用于数据的存取 。其中 示意数据库 构造时 可以 使用下面的对象:DataBase、TableDef、Field、Index,以及三个 集中(Collection):TableDefs、Fields和Indexes 。每一个 集中都是由若干个对象构成的,这些数据对象的 集中 可以 彻底看作是一个数组,并按数组的 步骤来调用 。
一旦数据库对象 构建后,就 可以用它对数据库的 构造进行 批改和数据 解决 。
关于非Access数据库,大 部分都是对应于一个目录,所以 可以 使用VB的MkDir语句先生成一个目录,亦即新建一个数据库 。而每一个非Access数据库文件可看作是此目录下的一个数据表(Table),但实际上它们是 彼此独立的 。
下面是新建一个FoxPro 2.5 格局数据库的程序实例 。
Sub CreateNew ( )
Dim Db1 As database, Td As TableDefs
Dim T1 As New Tabledef,F1 As New Field, F2 As New Field, F3 As New Field
Dim Ix1 As New Index
Dim Path As String
Const DB_TEXT = 10,DB_INTEGER = 3
ChDir "\"
Path$ = InputBox( "请输入新路径名:", "输入对话框" )
MkDir Path$ ’新建一个子目录
Set Db1 = OpenDatabase(Path$, True, False, "FoxPro 2.5;")
Set Td = Db1.TableDefs
T1.Name = "MyDB" ’新建一个数据表,数据表名为MyDB
F1.Name = "Name", F1.Type = DB_TEXT, F1.Size = 20
F2.Name = "Class", F2.Type = DB_TEXT, F2.Size = 20
F3.Name = "Grade", F3.Type = DB_INTEGER
T1.Fields.Append F1 ’向数据表中增加这些字段
T1.Fields.Append F2
T1.Fields.Append F3
Ix1.Name = "Name" ,Ix1.Fields = "Name", Ix1.Primary = True ’新建索引
T1.Indexes.Append Ix1 ’向数据库的Indexes 集中中增加新的索引
Td.Append T1 ’向TableDefs 集中中增加新表
Db1.Close ’必须先关闭数据库对象再退出
End Sub
  在此段程序中值得 留神的是,对非Access数据库的新建不用CreateDatabase函数,而是用OpenDatabase函数,这点与Access数据库大不一样,但也仅仅是针对非Access数据库而言 威力用OpenDatabase函数来新建一个数据库对象 。
在VB中,外来数据库的不同 格局只在OpenDatabase函数的最终一个参数Connect中有所体现,不同 格局的外来数据库其Connect参数值也不同,除此以外,在VB专业版中其编程的 步骤和步骤及技巧是 根本 雷同的 。
新建子目录后,不能用ChDir语句进入它,不然会浮现“‘MyDB’ is not a valid path”的 舛误 。同时,对F1、F2、F3等新建字段对象的定义也必须分别定义,不然会浮现“Element not defined”(变量未定义)的 舛误 。
通过 定然的编程技巧还 可以实现非Access数据库的库 构造的拷贝,下面是一段相应的程序 。
Function GetPos( TFname$ ) ’此自定义函数 实现对 引路径文件名中最终一个“”符号的定位
Dim I As Integer,Tmp As String
Tmp$ = TFname$
For I = 0 To 255
Pos% = Pos% + InStr( 1, Tmp$, "\" )
E1% = InStr( 1, Tmp$, "\" )
Tmp$ = Right$( Tmp$, Len(TFname$) - Pos% )
If E1% = 0 Then ’找到最终一个“”符号的位置,并记下来
GetPos = Pos%
Exit For
End If
Next I
End Funtion
Sub CopyStruc( )
Dim Db1 As database, Ds1 As Dynaset,Td As TableDefs, Fld As Fields
Dim Fname,SourceF,DestF,Path As String,Pos1 As Integer
CMD1.Filter = "FoxPro数据库文件(*.DBF)|*.DBF|所有文件|*.*" ’CMD1为一个对话框的控制名
CMD1.DialogTitle = "调入Ms FoxPro数据库文件"
CMD1.FilterIndex = 1
CMD1.Action = 1
DestF$ = InputBox$( "请输入 指标文件名:", "输入对话框" )
If CMD1.FileName = “ ”Or DestF$ = " " Then
MsgBox "源文件或 指标文件名为空"
Exit Sub
Else
SourceF$ = CMD1.Filename
End If
FileCopy SourceF$, DestF$
Pos1% = GetPos( SourceF$ )
Path$ = Left$( SourceF$, Pos1% ) ’ 获得源文件所在的路径名
Fn$ = Left$( DestF$, InStr(1, DestF$, ".") - 1 ) ’ 获得新文件的数据库名
’Fn$为实际的Foxpro数据库名,也即CreateDynaset函数内的source属性值
Set Db1 = OpenDatabase( Path$, True, False, "FoxPro 2.5;" )
Set Ds1 = Db1.CreateDynaset( Fn$ )
If Ds1.EOF And Ds1.BOF Then ’数据库内的无记录则退出
TotalNum% = 0
MsgBox "此数据表为空表!"
Exit Sub
End If
’删除记录,保留库 构造
Ds1.MoveFirst
Do
Ds1.Delete
Ds1.MoveNext
Loop Until Ds1.EOF
End Sub
  可见,拷贝库 构造的 步骤在于把一个已存在的数据库拷贝到一个新文件中, 而后再删除新文件内的所有记录,保留其库 构造,得到的便是一个新建的库 构造 完全的空库 。

  (二)非Access数据库的动态调入
  在实际 利用的众多状况下, 时常需求在对一些事先并不晓得其具体库 构造的数据库进行调入、显示及打印其记录 。 因此实现未知 格局数据库的动态调入也是评介VB数据库 利用程序兼容性的一个主要 标记 。
在VB中,网格控件十分 合 实用于阅读数据库中的数据, 惟独把数据放入网格即可 。
在 使用网格时动态调入的 要害在于记录(Colume)内容和字段(Row)内容(包含字段的名称、类型、值等)的读取, 因此生成一个 可以对应于一个或多个数据表中的所有或 部分记录的Dynaset对象是十分必要的 。Dynaset对象还 可以是一个动态 查问的 后果,能进行记录的增加、删除和 批改等操作 。
下面是一段用网格显示FoxPro数据库的程序 。
Sub DBLoad( )
Dim Db1 As database, Ds1 As Dynaset,Td As TableDefs,Fld As Fields
Dim Fname,Tmp,Path ToTalNum As String,I,J,Pos1 As Integer
Dim MyNum ’定义一个变体型数据
CMD1.Filter = "FoxPro数据库文件(*.DBF)|*.DBF|所有文件|*.*"
CMD1.DialogTitle = "调入Ms FoxPro数据库文件"
CMD1.FilterIndex = 1
CMD1.Action = 1
Fname$ = CMD1.Filename
Pos1% = GetPos( Fname$ )
Path$ = Left$( Fname$, Pos1% )
Tmp$ = Right$( Fname$, Len(Fname$)-Pos1)
Fn$ = Left$( Tmp$, Instr( 1,Tmp$,“.”) - 1 )
Set Db1 = OpenDatabase( Path$, True, False, "FoxPro 2.5;" )
Set Ds1 = Db1.CreateDynaset( Fn$ )
If Ds1.EOF And Ds1.BOF Then '数据库表内无记录则退出
TotalNum = 0
MsgBox "此数据表为空表!"
Exit Sub
Else '显示数据库表内的实际记录数
Ds1.MoveLast
TotalNum = Ds1.RecordCount
Grid1.Rows = TotalNum + 1 ’置网格的实际行数
Total.Caption = Str$(TotalNum)
End If
'置网格的实际列数并置每列的宽度
Set Td = Db1.TableDefs
Set Fld = Td( Fn$ ).Fields
Grid1.Cols = Fld.Count + 1
Grid1.ColWidth(0) = 600
For I = 1 To Fld.Count
Grid1.ColWidth(I) = 1500
Next I
'在网格的第一行内填入字段名
Grid1.Row = 0, Grid1.Col = 0
Grid1.Text = "序号"
For I = 1 To Fld.Count
Grid1.Col = I
Grid1.Text = Fld(I - 1).Name
Next I
'在网格中填入相应的数据
Ds1.MoveFirst
I = 1
Do While Not Ds1.EOF
Grid1.RowHeight(I) = 300
Grid1.Row = I
Grid1.Col = 0
Grid1.Text = I
For J = 1 To Fld.Count
Grid1.Col = J
MyNum = Ds1.Fields(J - 1).Value
'对记录的数据类型进行推断后做相应的 解决
If IsNumeric( MyNum ) Or IsDate( MyNum ) Then
Grid1.Text = Str$( Ds1.Fields(J - 1).Value )
Else If VarType( MyNum ) = 8 Then
Grid1.Text = Ds1.Fields(J - 1).Value
Else If VarType( MyNum ) = 0 Or VarType( MyNum ) = 1 Then
Grid1.Text = " "
End If
On Error Resume Next
Next J
Ds1.MoveNext
I = I + 1
Loop
Ds1.Close
Db1.Close
Exit Sub
  最终应记住,在VB的数据库 利用程序运行之前, 定然要在AUTOEXEC.BAT文件中加入一句SHARE.EXE /L:500 。
以上所有程序均在Pentium/166机、中文Windows95下用VB4调试通过 。

  四、 完毕语
  
对非Access数据库的兼容是VB数据库编程中不可分割的主要 部分 。 因此娴熟 主宰 使用DAO 步骤对非Access数据库的编程是极为主要的 。而且, 定然编程技巧的 利用也有助于 补偿VB对外来数据库 支撑的缺乏 。