VB数据库编程技术123

来源:百度文库 编辑:神马文学网 时间:2024/04/26 05:08:08



9.1.1  VB中的数据访问
    VB提供的数据库引擎叫Jet。VB提供了两种与Jet数据库引擎接口的方法:Data控件(Data Control)和数据访问对象(DAO)。Data控件只提供了有限的不需编程就能访问现存数据库的功能,而DAO模型则是全面控制数据库的完整编程接口。这两种方法不是互斥的,实际上,它们可以同时使用。
    VB中的数据库编程就是创建数据访问对象,这些数据访问对象对应于被访问的物理数据库的不同部分,如Database(数据库)、Table(表)、Field(字段)和Index(索引)对象。用这些对象的属性和方法来实现对数据库的操作。VB通过DAO和Jet引擎可以识别三类数据库:
 1. VB数据库:也称为本地数据库,这类数据库文件使用与Microsoft Access相同的格式。Jet引擎直接创建和操作这些数据库并且提供了最大程度的灵活性和速度。
    2. 外部数据库:VB可以使用几种比较流行的“索引顺序访问文件方法(ISAM)”数据库,包括:dDase III、dBase IV、FoxPro 2.0和2.5以及Paradox 3.x和4.x。在VB中可以创建和操作所有这些格式的数据库,也可以访问文本文件数据库和Excel或Lotus l-2-3电子表格文件。
    3. ODBC数据库:包括符合ODBC标准的客户机/服务器数据库,如Microsoft SQL Server。如果要在VB中创建真正的客户机/服务器应用程序,可以使用ODBC Direct直接把命令传递给服务器处理。
9.1.2  VB数据库体系结构
 VB提供了基于Microsoft  Jet数据库引擎的数据访问能力,Jet引擎负责处理存储、检索、更新数据的结构,并提供了功能强大的面向对象的DAO编程接口。
VB数据库应用程序的组成
 VB数据库应用程序包含三部分,如图9.1所示。
 
 
 
 图9.1  VB数据库应用程序的组成
 
 数据库引擎位于程序和物理数据库文件之间。这把用户与正在访问的特定数据库隔离开来,实现“透明”访问。不管这个数据库是本地的VB数据库,还是所支持的其他任何格式的数据库,所使用的数据访问对象和编程技术都是相同的。
   (1)用户界面和应用程序代码
    用户界面是用户所看见的用于交互的界面,它包括显示数据并允许用户查看或更新数据的窗体。驱动这些窗体的是应用程序的VB代码,包括用来请求数据库服务的数据访问对象和方法,比如添加或删除记录,或执行查询等。
   (2)Jet引擎
    Jet引擎被包含在一组动态链接库(DLL)文件中。在运行时,这些文件被链接到VB程序。它把应用程序的请求翻译成对.mdb(Access文件后缀)文件或其他数据库的物理操作。它真正读取、写入和修改数据库,并处理所有内部事务,如索引、锁定、安全性和引用完整性。它还包含一个查询处理器,接收并执行SQL查询,实现所需的数据操作。另外,它还包含一个结果处理器,用来管理查询所返回的结果。
   (3)数据库
    数据库是包含数据库表的一个或多个文件。对于本地VB或Access数据库来说,就是.mdb文件。对于ISAM数据库,它可能是包含.dbf(dBASE文件后缀)文件或其他扩展名的文件。或者,应用程序可能会访问保存在几个不同的数据库文件或格式中的数据。但无论在什么情况下,数据库本质上都是被动的,它包含数据但不对数据作任何操作。数据操作是数据库引擎的任务。
 2.数据库应用程序的存放
    数据库应用程序的这三个部分可以被分别放置在不同的位置上。可以把它们都放在一台计算机上,供单用户应用程序使用,也可以放置在通过网络连接起来的不同计算机上。例如,数据库可以驻留在中央服务器上,而用户界面(即应用程序)则驻留在几个客户机上,让许多用户访问相同的数据。
 脱离开应用程序本身,将数据存放在另一台机器上的数据库应用程序,有远程数据库和客户机/服务器数据库两种结构。它们的不同点如图9.2所示。
              客户机/服务器                   远程

 服务器

 


 客户机
 
 图9.2  客户机/服务器数据库与远程数据库的存放
    在客户机/服务器系统中,数据库引擎和数据库一起被放置在服务器上。数据库引擎可以同时对多个客户机的应用程序提供服务、操作数据库并对每个本地应用程序返回所请求的记录。在远程系统中,数据库引擎与用户应用程序在相同的计算机上,只有数据库驻留在远程计算机上。
 Jet数据库引擎不是客户机/服务器引擎,它是驻留在DLL文件中的本地数据库引擎,在运行时被动态地链接到VB应用程序中。如果程序在不同的工作站上有许多备份,那么每个备份都将有它自己的Jet数据库引擎在本地的备份。在VB中,通过连接到ODBC数据源,如Microsoft SQL Server等,可直接把查询传递给服务器数据库引擎,就可以创建客户机/服务器应用程序。
 9.2本地数据库设计(ACCESS)
   VB中创建数据库的途径主要有:
 (1)可视化数据管理器:使用可视化数据管理器,不需要编程就可以创建Jet数据库。
 (2)DAO:使用VB的DAO部件可以通过编程的方法创建数据库。
 (3)Microsoft Access:因为Microsoft Access使用了与VB相同的数据库引擎和格式,所以,用Microsoft Access创建的数据库和直接在VB中创建的数据库是一样的。
 (4)数据库应用程序:像FoxPro、dBase或ODBC客户机/服务器应用程序这样的产品,可以作为外部数据库,VB可通过ISAM或ODBC驱动程序来访问这些数据库。
9.2.1可视化数据管理器
     数据管理器(Data  Manager)是VB的一个传统成员,它可以用于快速地建立数据库结构及数据库内容。VB的数据管理器实际上是一个独立的可单独运行的应用程序    Visdata.exe。它随安装过程放置在VB目录中,可以单独运行,也可以在VB开发环境中启动。凡是VB有关数据库的操作,比如数据库结构的建立、记录的添加及修改以及用ODBC连接到服务器端的数据库如SQL Server,都可以利用此工具来完成。
    1.启动数据管理器
 选择“外接程序”菜单下的“可视化数据管理器”项就可以启动数据管理器,打开“VisData”窗口。
    2.工具栏按钮
    VisData 窗口的工具栏提供了三组共9个按钮,为了说明这些按钮所提供的功能,我们利用VB提供的一个例子——数据库Biblio.mdb来介绍。
 Biblio.mdb存放在VB98目录中,单击“文件”菜单中的“打开数据库”级联菜单的“Microsoft  Access”项,即可在出现的对话框中看到Biblio.mdb,选中并打开它,打开后的VisData窗口如图9.3所示。
 我们可以看到,在这个MDI窗口内包含两个子窗口:数据库窗口和SQL语句窗口。数据库窗口显示了数据库的结构,包括表名、列名、索引。SQL语句窗口可用于输入一些SQL命令,针对数据库中的表进行查询操作。
 
 
 图9.3  VisData窗口
 
 下面我们对工具栏上的按钮进行简单的说明。
 (1)类型群组按钮
 工具栏的第一组按钮,它可以设置记录集的访问方式,具体为:
    ①表类型记录集按钮(最左边的按钮):当以这种方式打开数据库中的数据时,所进行的增、删、改、查等操作都是直接更新数据库中的数据。
    ②动态集类型记录集按钮(中间的按钮):使用这种方式是先将指定的数据打开并读入到内存中,当用户进行数据编辑操作时,不直接影响数据库中的数据。使用这种方式可以加快运行速度。
 ③快照类型记录集(最右边的拉钮):以这种类型显示的数据只能读不能修改,适用于只查询的情况。
 (2)数据群组按钮
 工具栏的中间一组按钮。用于指定数据表中数据的显示方式。先用鼠标在要显示风格的按钮上单击一下,然后选中某个要显示数据的数据表,单击鼠标右键,在弹出的菜单上选择“打开”,则此表中的数据就以所要求的形式显示出来。
 (3)事务方式群组按钮
工具栏的最后一组按钮用于进行事务处理。
9.2.2具体实现
    1.建立数据库
 对数据管理器的基本功能有了初步的认识后,我们看一下如何利用它来建立数据库。我们这里所建立的数据库student.mdb(学生数据库)中各表如下:

 


 (1)建立数据库结构
    单击“文件”菜单中的“新建”命令,在“新建”级联菜单中选择“Microsoft  Access”,再选择“版本7.0 MDB”项,在“选择要创建的Microsoft Access数据库”窗口中选定新建数据库的路径并输入数据库名,这里为student.mdb。
    这样一个新的数据库就建立好了,下面就要在此数据库中添加数据表了。
   (2)添加数据表
 将鼠标移到数据库窗口区域内,单击鼠标右键,在弹出的菜单中选择“新建表”命令,出现“表结构”对话框,利用对话框我们可以建立数据表的结构。
 我们首先建立基本情况表。在“表名称”中输入“基本情况”,然后添加基本情况表的字段,单击“添加字段”按钮,出现“添加字段”对话框,在此对话框中填入“学号”字段的信息。
    按顺序输入“姓名”、“性别”、“专业”、“出生年月”、“照片”、“备注”字段,然后按“关闭”按钮返回到“表结构”对话框中。
 (3)建立索引
 建立了表的结构后就可以建立此表的索引了,这样可以加快检索速度。单击“添加索引”按钮,会出现如图9.4所示的对话框,通过此对话框可以将数据表的某些字段设置为索引。在“名称”字段中输入索引的名称,然后从下边的“索引的字段”列表中选择作为索引的字段,我们这里选择的是“学号”。
 
 图9.4 设置索引对话框
 
    如果需要建立多个索引,则每完成一项索引后,单击“确定”按钮,然后继续下一个索引的设置。设置完毕后,单击“关闭”按钮返回到“表结构”对话框。
2.录入数据
    数据表结构建立好之后,就可以向表中输入数据了,数据管理器提供了简单的数据录入功能。
 首先在工具栏上选定DBGrid显示风格的按钮,然后在要录入数据的数据表上单击鼠标右键,选择“打开”选项,则出现以网格风格显示数据的窗口,如果此表中已有数据,则此时会显示出此表中的全部数据;若此表中无数据,则会显示出一个空表。如图9.5所示。我们这里是以“基本情况”表为例,并且输入了部分数据后的情况。
 
  图9.5    录入数据
 3.建立查询
 数据表建立好之后,如果数据表中已经有数据,就可以对表中的数据进行有条件或无条件的查询。VB的数据管理器提供了一个图形化的设置查询条件的窗口——查询生成器。选择“实用程序”菜单下的“查询生成器”,或在数据库窗口区域单击鼠标右健,然后在弹出的菜单中选择“新查询”,即可出现“查询生成器”对话框,如图9.6所示。
 假设我们要查询学号为110002的学生基本情况,可按下述步骤进行:
 (1)首先选择要进行查询的数据表,单击表列表框中的“基本情况”表。
 (2)在“字段名称”字段中选定“基本情况.学号”。
 (3)单击“运算符”列表,选择“=”。
 (4)单击“列出可能的值”按钮,在“值”字段中输入110002。
 (5)单击“将And加入条件”按钮,将条件加入“条件”列表框中。
 (6)在“要显示的字段”列表框中,选定所需显示的字段。注意,这里所选的字段就是我们在查询结果中要看的字段。
 (7)单击“运行”按钮,在随后出现的VisData对话框中,选择“否”,并进一步选择“运行”,即可看到查询结果。
(8)单击“显示“按钮,在随后出现的“SQL Query”窗口中,显示刚建立的查询所对应的SQL语句。

 图9.6  “查询生成器”对话框

9.3  数据控件
    Data控件是Visual Basic访问数据库的一种利器,它能够利用三种Recordset对象来访问数据库中的数据,数据控件提供有限的不需编程而能访问现存数据库的功能,允许将Visual Basic的窗体与数据库方便地进行连接。要利用数据控件返回数据库中记录的集合,应先在窗体上画出控件,再通过它的三个基本属性Connect、DatabaseName和RecordSource设置要访问的数据资源。
9.3.1  数据控件属性
     1.Connect属性
    Connect属性指定数据控件所要连接的数据库类型,Visual Basic默认的数据库是Access的MDB文件,此外,也可连接DBF、XLS、ODBC等类型的数据库。
    2.DatabaseName属性
    DatabaseName属性指定具体使用的数据库文件名,包括所有的路径名。如果连接的是单表数据库,则DatabaseName属性应设置为数据库文件所在的子目录名,而具体文件名放在RecordSource属性中。
    例如,要连接一个Microsoft Access的数据库C:\Student.mdb,则设置DatabaseName=”C:\Student.mdb",Access数据库的所有表都包含在一个MDB文件中。如果连接一个FoxPro数据库如C:\VB6\stu_fox.dbf,则DatabaseName=”C:\VB6”,RecordSource=”stu_fox.dbf”,stu_fox数据库只含有一个表。
    3.RecordSource属性
 RecordSource确定具体可访问的数据,这些数据构成记录集对象Recordset。该属性值可以是数据库中的单个表名,—个存储查询,也可以是使用SQL查询语言的一个查询字符串。
 例如,要指定Student.mdb数据库中的基本情况表,则RecordSource=”基本情况”。而RecordSource=”Select  From 基本情况Where专业=’物理’ ”,则表示要访问基本情况表中所有物理系学生的数据。
    4.RecordType属性
    RecordType属性确定记录集类型。
    5.EofAction和BofAction属性
 当记录指针指向Recordset对象的开始(第一个记录前)或结束(最后一个记录后)时,数据控件的EofAction和BofAction属性的设置或返回值决定了数据控件要采取的操作。属性的取值如表9.1所示。
 
表9.1  EofAction和BofAction属性
 属性 取值  操作 

BofAction  0 控件重定位到第—个记录 
  1 移过记录集开始位,定位到一个无效记录,触发数据控件对第一个记录的无效事件Validate 


EofAction  0 控件重定位到最后—个记录 
  1 移过记录集结束位,定位到一个无效记录,触发数据  控件对最后一个记录的无效事件Validate    
  2 向记录集加入新的空记录,可以对新记录进行编辑,移动记录指针,新记录写入数据库 
 
 在Visual Basic中,数据控件本身不能直接显示记录集中的数据,必须通过能与它绑定的控件来实现。可与数据控件绑定的控件对象有文本框、标签、图像框、图形框、列表框、组合框、复选框、网格、DB列表框、DB组合框、DB网格和OLE容器等控件。要使绑定控件能被数据库约束,必需在设计或运行时对这些控件的两个属性进行设置:
 (1)DataSource属性
 DataSource属性通过指定—个有效的数据控件连接到一个数据库上。
 (2)DataField属性
 DataField属性设置数据库有效的字段与绑定控件建立联系。
 绑定控件、数据控件和数据库三者的关系如图9.7所示。
 


图9.7 绑定控件、数据控件和数据库三者的关系

    当上述控件与数据控件绑定后,Visual Basic将当前记录的字段值赋给控件。如果修改了绑定控件内的数据,只要移动记录指针,修改后的数据会自动写入数据库。数据控件在装入数据库时,它把记录集的第一个记录作为当前记录。当数据控件的BofAction属性值设置为2时,当记录指针移过记录集结束位,数据控件会自动向记录集加入新的空记录。
 例9.1  建立student.mdb数据库,它包含两个表:“基本情况”表和“学生成绩表”。参见表9.2和表9.3。
 表9.2  学生基本情况表结构
字段名 类型 宽度 
学号 Text 6 
姓名 Text 10 
性别 Text 2 
专业 Text 10 
出生年月 Date 8 
照片 Binary 0 
 
 表9.3 学生成绩表结构
字段名 类型 宽度 
学号 Text 6 
课程 Text 10 
成绩 Long 4 
学期 Text 2 
 
 用可视化数据管理器建立以上设计的数据库及其表,表中数据可自行录入。
 例9.2   设计一个窗体用以显示建立的student.mdb数据库中基本情况表的内容。
 基本情况表包含了6个字段,故需要用6个绑定控件与之对应。这里用一个图形框显示照片和5个文本框显示学号、姓名等数据。本例中不需要编写任何代码,具体操作步骤如下:
 (1)参考如图9.8所示窗体,在窗体上放置1个数据控件,一个图形框、5个文本框和5个标签控件。5个标签控件分别给出相关的提示说明。
 
 图9.8  显示Student.mdb基本情况表的数据
 (2)将数据控件Data1的Connect属性指定为Access类型,DatabaseName属性连接数据库Student.mdb,RecordSource属性设置为“基本情况”表。
 (3)图形框和5个文本框控件Text1~Text5的DataSource属性都设置成Data1。通过单击这些绑定控件的DataField属性上的“…”按钮,将下拉出基本情况表所含的全部字段,分别选择与其对应的字段照片、学号、姓名、性别、专业和出生年月,使之建立约束关系。
    运行该工程即可出现图9.8所示效果。5个文本框分别显示基本情况表内的字段:学号、姓名、性别、专业和出生年月的内容,图形框显示每个学生的照片。
    使用数据控件对象的4个箭头按钮可遍历整个记录集中的记录。单击最左边的按钮显示第l条记录;单击其旁边的按钮显示上一条记录;单击最右边的按钮显示最后一条记录;单击其旁边的按钮显示下—条记录。数据控件除了可以浏览Recordset对象中的记录外,同时还可以编辑数据。如果改变了某个字段的值,只要移动记录,这时所作的改变存入数据库中。
    Visual Basic 6.0提供了几个比较复杂的网格控件,几乎不用编写代码就可以实现多条记录数据显示。当把数据网格控件的DataSource属性设置为一个Data控件时,网格控件会被自动地填充,并且其列标题会用Data控件的记录集里的数据自动地设置。
 例9.3  用数据网格控件MsFlexGrid显示Student.mdb数据库中基本情况表的内容。
 MsFlexGrid控件不是Visual Basic工具箱内的默认控件,需要在开发环境中选择“工程|部件”菜单命令,并在随即出现的对话框中选择“MicroSoft FlexGrid Control 6.0”选项,将其添加到工具箱中。本例所用控件的属性设置如表9.4所示。请读者自行比较不可卷动列属性FixedCols=0与FixedCols=1的区别。Form启动后自动显示如图9.9所示窗口。
                         表9.4  控件属性
默认控件名 其它属性设置 
Data1 DatabaseName=”c:\student.mdb”
RecordsetType=0
RecordSource=”基本情况” 
MSFlexGrid1 DataSource=Data1
FixCols=0 


 图9.9使用数据网格控件
9.3.2数据控件的事件
    1.Reposition事件
    Reposition事件发生在一条记录成为当前记录后,只要改变记录集的指针使其从一条记录移到另一条记录,会产生Reposition事件。通常,可以在这个事件中显示当前指针的位置。例如,在例9.2的Data1_Reposition事件中加入如下代码:
Private Sub Data1_Reposition()
  Data1.Caption = Data1.Recordset.AbsolutePosition + 1
End Sub
    这里,Recordset为记录集对象,AbsolutePosition属性指示当前指针值(从0开始)。当单击数据控件对象上的箭头按钮时,数据控件的标题区会显示记录的序号。
    2.Validate事件
 当要移动记录指针、修改与删除记录前或卸载含有数据控件的窗体时都触发Validate事件。Validate事件检查被数据控件绑定的控件内的数据是否发生变化。它通过Save参数(True或False)判断是否有数据发生变化,Action参数判断哪—种操作触发了Validate事件。参数可为表9.5中的值。
 
 表9.5 Validate事件的Action参数
Action值  描述 Action值  描述 
 0 取消对数据控件的操作  6 Update 
 1 MoveFirst  7 Delete 
 2 MovePrevious  8 Find 
 3 MoveNext  9 设置Bookmark 
 4 MoveLast  10 Close 
 5 AddNew  11 卸载窗体 
  
 一般可用Validate事件来检查数据的有效性。例如,在例9.2中,如果不允许用户在数据浏览时清空性别数据,可使用下列代码:
Private Sub Data1_Validate(Action As Integer, Save As Integer)
  If Save And Len(Trim(Text3)) = 0 Then
    Action = 0
    MsgBox " 性别不能为空!"
 End If
End Sub   
 此代码检查被数据控件绑定的控件Text3内的数据是否被清空。如果Text3内的数据发生变化,则Save参数返回True,若性别对应的文本框Text3被置空,则通过Action=0取消对数据控件的操作。
 
9.3.3  数据控件的常用方法
    数据控件的内置功能很多,可以在代码中用数据控件的方法访问这些属性。
 1.Refresh方法
 如果在设计状态没有为打开数据库控件的有关属性全部赋值,或当RecordSource在运行时被改变后,必须使用数据控件的Refresh方法激活这些变化。在多用户环境下,当其他用户同时访问同一数据库和表时,Refresh方法将使各用户对数据库的操作有效。
 例如:将例9.2的设计参数改用代码实现,使所连接数据库所在的文件夹可随程序而变化:
Private Sub Form_Load( )
  Dim mpath As String
  Mpath=App.Path    ’获取当前路径
  If Right(mpath,1)<>”/” Then mpath=mpath+”/”
  Data1.DatabaseName=mpath+”Student.mdb”      ’连接数据库
  Data1.RecordSource=”基本情况”               ’构成记录集对象
  Data1.Refresh                               ’激活数据控件
End Sub
 2.UpdateControls方法
 UpdateControls方法可以将数据从数据库中重新读到被数据控件绑定的控件内。因而我们可使用UpdateControls方法终止用户对绑定控件内数据的修改。
    例如:将代码Data1.UpdateControts放在一个命令按钮的Click事件中,就可以实现对记录修改的功能。
    3. UpdateRecord方法
 当对绑定控件内的数据修改后,数据控件需要移动记录集的指针才能保存修改。如果使用UpdateRecord方法,可强制数据控件将绑定控件内的数据写入到数据库中,而不再触发Validate事件。在代码中可以用该方法来确认修改。
 
9.3.4  记录集的属性与方法
 
    由RecordSource确定的具体可访问的数据构成的记录集Recordset也是一个对象,因而,它和其他对象一样具有属性和方法。下面列出记录集常用的属性和方法。
 1.AbsolutePosition属性
 AbsolutePosition返回当前指针值,如果是第1条记录,其值为0,该属性为只读属性。
 2.Bof和Eof的属性
    Bof判定记录指针是否在首记录之前,若Bof为True,则当前位置位于记录集的第1条记录之前。与此类似,Eof判定记录指针是否在末记录之后。
 3.Bookmark属性
    Bookmark属性的值采用字符串类型,用于设置或返回当前指针的标签。在程序中可以使用Bookmark属性重定位记录集的指针,但不能使用AbsolutePostion属性。
 4.Nomatch属性
    在记录集中进行查找时,如果找到相匹配的记录,则Recordset的NoMatch属性为False,否则为True。该属性常与Bookmark属性一起使用。
 5.RecordCount属性
    RecordCount属性对Recordset对象中的记录计数,该属性为只读属性。在多用户环境下,RecordCount属性值可能不准确,为了获得准确值,在读取RecordCount属性值之前,可使用MoveLast方法将记录指针移至最后一条记录上。
 6.Move方法
    使用Move方法可代替对数据控件对象的4个箭头按钮的操作遍历整个记录集。5种Move方法是:
    (1)MoveFirst方法:移至第1条记录。
    (2)MoveLast方法:移至最后一条记录。
    (3)MoveNext方法:移至下一条记录。
 (4)MovePrevious方法:移至上一条记录。
 (5)Move [n] 方法:向前或向后移n条记录,n为指定的数值。
 例9.4  在窗体上用4个命令按钮代替例9.2数据控件对象的4个箭头按钮的操作。
 在例9.2的基础上,窗体上增加4个命令按钮,将数据控件的Visible属性设置为False,如图9.10所示。通过对4个命令按钮的编程代替对数据控件对象的4个箭头按钮的操作。
 

图9.10  用按钮代替数据控件对象的箭头按钮

 命令按钮Command1_Click事件移至第1条记录,代码如下:
Private Sub Command1_Click()
 Data1.Recordset.MoveFirst
End Sub
 命令按钮Command4_Click事件移至最后一条记录,代码如下:
Private Sub Command4_Click()
   Data1.Recordset.MoveLast
End Sub
    另外两个按钮的代码需要考虑Recordset对象的边界的首尾,如果越界,则用MoveFirst方法定位到第1条记录或用MoveLast方法定位到最后一条记录。程序代码如下:
Private Sub Command2_Click()
  Data1.Recordset.MovePrevious
   If Data1.Recordset.BOF Then Data1.Recordset.MoveFirst
End Sub
Private Sub Command3_Click()
  Data1.Recordset.MoveNext
   If Data1.Recordset.EOF Then Data1.Recordset.MoveLast
End Sub
 7.Find方法
 使用Find方法可在指定的Dynaset或Snapshot类型的Recordset对象中查找与指定条件相符的一条记录,并使之成为当前记录。4种Find方法是:
    (1)FindFirst方法:从记录集的开始查找满足条件的第1条记录。
    (2)FindLast方法:从记录集的尾部向前查找满足条件的第l条记录。
    (3)FindNext方法:从当前记录开始查找满足条件的下一条记录。
    (4)FindPrevious方法:从当前记录开始查找满足条件的上一条记录。
 4种Find方法的语法格式相同:
 数据集合.Find方法  条件
    搜索条件是一个指定字段与常量关系的字符串表达式。在构造表达式时,除了用普通的关系运算外,还可以用Like运算符。
    例如:语句 “Data1.Recordset.FindFirst  专业=’物理’”表示在由Data1数据控件所连接的数据库Student.mdb的记录集内查找专业为“物理”的第l条记录。这里,“专业”为数据库Student记录集中的字段名,在该字段中存放专业名称信息。要想查找下一条符合条件的记录,可继续使用语句:”Data1.Recordset.FindNext  专业=’物理’”。
    又例如:要在记录集内查找专业名称中带有“建”字的专业:
    Data1.Recordset.FindFirst 专业 Like ”*建*”
字符串“*建*”匹配字段专业中带有“建”字字样的所有专业名称字符串。
    需要指出的是Find方法在找不到相匹配的记录时,当前记录保持在查找的始发处,NoMatch属性为True。如果Find方法找到相匹配的记录,则记录定位到该记录,Recordset的NoMatch属性为False。
 8.Seek方法
    使用Seek方法必须打开表的索引,它在Table表中查找与指定索引规则相符的第1条记录,并使之成为当前记录。其语法格式为:
    数据表对象.seek comparison,keyl,key2…
    Seek允许接受多个参数,第1个是比较运算符comparison,Seek方法中可用的比较运算符有=、>=、>、<>、<、<=等。
    在使用Seek方法定位记录时,必须通过Index属性设置索引。若在记录集中多次使用同样的Seek方法(参数相同),那么找到的总是同一条记录。
    例如:假设数据库Student内基本情况表的索引字段为学号,满足学号字段值大于等于110001的第1条记录可使用以下程序代码:
Data1.RecordsetType = 0                ’设置记录集类型为Table
Data1.RecordSource = "基本情况"        ’打开基本情况表单
Data1.Refresh
Data1.Recordset.Index = "jbqk_no"      ’打开名称为jbqk_no的索引
Data1.Recordset.Seek ">=", "110001"
9.3.5 数据库记录的增、删、改操作
    Data控件是浏览表格并编辑表格的好工具,但怎么输入新信息或删除现有记录呢?这需要编写几行代码,否则无法在Data控件上完成数据输入。数据库记录的增、删、改操作需要使用AddNew、Delete、Edit、Update和Refresh方法。它们的语法格式为:
    数据控件.记录集.方法名
 1.增加记录
 AddNew方法在记录集中增加新记录。增加记录的步骤为:
 (1)调用AddNew方法。
    (2)给各字段赋值。给字段赋值格式为:Recordset.Fields(”字段名”)=值。
    (3)调用Update方法,确定所做的添加,将缓冲区内的数据写入数据库。
    注意:如果使用AddNew方法添加新的记录,但是没有使用Update方法而移动到其他记录,或者关闭记录集,那么所做的输入将全部丢失,而且没有任何警告。当调用Update方法写入记录后,记录指针自动返回到添加新记录前的位置上,而不显示新记录。为此,可在调用Update方法后,使用MoveLast方法将记录指针再次移到新记录上。
 2.删除记录
 要从记录集中删除记录的操作分为三步:
 (1)定位被删除的记录使之成为当前记录。
 (2)调用Delete方法。
 (3)移动记录指针。
    注意:在使用Delete方法时,当前记录立即删除,不加任何的警告或者提示。删除一条记录后,被数据库所约束的绑定控件仍旧显示该记录的内容。因此,你必须移动记录指针刷新绑定控件,—般采用移至下一记录的处理方法。在移动记录指针后,应该检查Eof属性。
 3.编辑记录
    数据控件自动提供了修改现有记录的能力,当直接改变被数据库所约束的绑定控件的内容后,需单击数据控件对象的任一箭头按钮来改变当前记录,确定所做的修改。也可通过程序代码来修改记录,使用程序代码修改当前记录的步骤为:
    (1)调用Edit方法。
    (2)给各字段赋值。
    (3)调用Update方法,确定所做的修改。
    注意:如果要放弃对数据的所有修改,可用Refresh方法,重读数据库,没有调用Update方法,数据的修改没有写入数据库,所以这样的记录会在刷新记录集时丢失。
 例9.5  在例9.2的基础上加入“新增”、“删除”、“修改”、“放弃”和“查找”钮,通过对5个按纽的编程建立增、删、改、查功能,如图9.11所示。
 

图9.11  编程建立增、删、改、查功能

    Command1_Click事件的功能根据按钮提示文字调用AddNew方法或Update方法,并且控制具他4个按钮的可用性。当按钮提示为“新增”时调用AddNew方法,并将提示文字改为“确认”,同时使“删除”按钮Command2、“修改”按钮Command3和“查找”按钮Command5不可用,而使“放弃”按钮Command4可用。新增记录后,需再次单击Command1调用Update方法确认添加的记录,再将提示文字再改为“新增”,并使“删除”、“修改”和“查找”按钮可用,而使“放弃”按钮不可用。程序中出现的On Error Resume Next语句是Visual Basic提供的错误捕获语句。该语句表示在程序运行时发生错误,忽略错误行,继续执行下一语句。
Private Sub Command1_Click()
  On Error Resume Next
  Command2.Enabled = Not Command2.Enabled
  Command3.Enabled = Not Command3.Enabled
  Command4.Enabled = Not Command4.Enabled
  Command5.Enabled = Not Command5.Enabled
  If Command1.Caption = "新增" Then
      Command1.Caption = "确认"
      Data1.Recordset.AddNew
      Text1.SetFocus
  Else
      Command1.Caption = "新增"
      Data1.Recordset.Update
      Data1.Recordset.MoveLast
  End If
End Sub
    命令按钮Command2_Click事件调用方法删除当前记录。当记录集中的记录全部被删除后,再执行Move语句将发生错误,这时由On Error Resume Next语句处理错误。
Private Sub Command2_Click()
  On Error Resume Next
  Data1.Recordset.Delete
  Data1.Recordset.MoveNext
  If Data1.Recordset.EOF Then Data1.Recordset.MoveLast
End Sub
    命令按钮Command3_Click事件的编程思路与Command1_Click事件类似,根据按钮提示文字调用Edit方法进入编辑状态或调用Update方法将修改后的数据写入到数据库,并控制其他3个按钮的可用性,代码如下:
Private Sub Command3_Click()
  On Error Resume Next
  Command1.Enabled = Not Command1.Enabled
  Command2.Enabled = Not Command2.Enabled
  Command4.Enabled = Not Command4.Enabled
  Command5.Enabled = Not Command5.Enabled
  If Command3.Caption = "修改" Then
      Command3.Caption = "确认"
      Data1.Recordset.Edit
      Text1.SetFocus
  Else
      Command3.Caption = "修改"
      Data1.Recordset.Update
  End If
End Sub
 命令按钮Command4_Click事件使用UpdateControls方法放弃操作,代码如下:
Private Sub Command4_Click()
  On Error Resume Next
  Command1.Caption = "新增"
  Command3.Caption = "修改"
  Command1.Enabled = True
  Command2.Enabled = True
  Command3.Enabled = True
  Command4.Enabled = False
  Command5.Enabled = True
  Data1.UpdateControls
  Dala1.Recordset.MoveLast
End Sub
 命令按钮Command5_Click事件根据输入专业使用SQL语句查找记录,代码如下:
Private Sub Command5_Click()
 Dim mzy As String
  mzy = InputBox$("请输入专业", "查找窗")
  Data1.RecordSource = "Select * From 基本情况 Where 专业 = '" & mzy & "'"
  Data1.Refresh
  If Data1.Recordset.EOF Then
    MsgBox "无此专业!", , "提示"
    Data1.RecordSource = "基本情况"
    Data1.Refresh
  End If
End Sub   
 上面的代码给出了数据表内数据处理的基本方法。需要注意的是:对于一条新记录或编辑过的记录必须要保证数据的完整性,这可通过Data1_Validate事件过滤无效记录。例如,下面的代码对学号字段进行测试,如果学号为空则输入无效。在本例中被学号字段所约束的绑定控件是Text1,可用Text1.DataChanged属性检测Text1控件所对应的当前记录中的字段值的内容是否发生了变化,Action=6表示Update操作(参见表9.5)。此外,使用数据控件对象的任一箭头按钮来改变当前记录,也可确定所做添加的新记录或对已有记录的修改,Action取值1~4分别对应单击其中一个箭头按钮的操作,当单击数据控件的箭头按钮时也触发Validate事件。
Private Sub Data1_Validate(Action As Integer, Save As Integer)
  If Text1.Text = "" And (Action = 6 Or Text1.DataChanged) Then
    MsgBox "数据不完整,必须要有学号!"
    Data1.UpdateControls
  End If
  If Action >= 1 And Action <= 4 Then
    Command1.Caption = "新增"
    Command3.Caption = "修改"
    Command1.Enabled = True
    Command2.Enabled = True
    Command3.Enabled = True
    Command4.Enabled = False
  End If
End Sub
 关于照片的输入,较简单的方法是通过剪贴板将照片图片复制到Picture1控件。在输入照片时,事先需要用扫描仪将照片扫描到内存或形成图形文件,通过一个图片编辑程序将照片装入剪贴板,然后再从剪贴板复制到Picture1控件。本例通过Picture1_DblClick事件来完成剪贴板到Picture1控件的复制,当移动记录指针时,Picture1控件内的照片存入数据库,此外,也可以使用OLE拖放技术将照片图形文件拖放到Picture1控件或其他图形容器内。
Private Sub Picture1_DblClick()
 Picture1.Picture = Clipboard.GetData
End Sub
9.4 ODBC
9.4.1 ODBC概述
 在传统的数据库管理系统中,每个数据库管理系统都有自己的应用程序开发接口(API),应用程序使用数据库系统所提供的专用开发工具(如嵌入式SQL语言)进行开发,这样的应用程序只能运行在特定的数据库系统环境下,适应性和可移植性比较差。在用户硬件平台或操作系统发生变化时,应用程序需要重新编写。嵌入式SQL语言的另一个缺点是它只能存取某种特定的数据库系统,因此一个应用程序只能连接同类的DBMS,而无法同时访问多个不同的DBMS,而在实际应用中通常是需要同时访问多个不同的DBMS的。例如,在一个单位中,财务、生产和技术等部门常根据自身专业的特点选择不同的DBMS,而建立企业级管理信息系统时,需要同时访问各个部门的数据库。这种情况下传统的数据库应用程序开发方法就难以实现。为了解决这些问题,微软公司开发了ODBC(Open DataBase Connectivity,即开放数据库互连)。
 ODBC 是Microsoft公司开发的一套开放数据库系统应用程序接口规范,目前它已成为一种工业标准,它提供了统一的数据库应用编程接口(API),为应用程序提供了一套高层调用接口规范和基于动态连接库的运行支持环境。使用ODBC开发数据库应用时,应用程序调用的是标准的ODBC函数和SQL语句,数据库底层操作由各个数据库的驱动程序完成。因此应用程序有很好的适应性和可移植性,并且具备了同时访问多种数据库管理系统的能力,从而彻底克服了传统数据库应用程序的缺陷。
9.4.2 ODBC体系结构
 ODBC驱动程序类似于Windows下的打印驱动程序,对用户来说,驱动程序屏蔽了不同对象(数据库系统或打印机)间的差异。同样地,ODBC屏蔽了DBMS之间的差异。ODBC的体系结构如图9.12所示。
 1.ODBC数据库应用程序
 应用程序的主要任务包括:建立与数据源的连接;向数据源发送SQL请求;接收并处理请求的结果;断开与数据源的连接等。
图9.12 ODBC的体系结构

 2.驱动程序管理器
 驱动程序管理器是一个Windows下的应用程序,在Windows 95和Windows NT环境下的控制面板上分别显示为“32位ODBC”图标和“ODBC”图标。如果在Windows 95和Windows NT环境下没有这个图标,说明没有安装ODBC驱动程序管理器。此软件可从Windows 95操作系统、Microsoft VC++、Microsoft VB等软件中获得。此管理器的主要作用是用来装载ODBC驱动程序、管理数据源、检查ODBC参数的合法性等。
 3.DBMS驱动程序
    ODBC应用程序不能直接存取数据库,它将所要执行的操作提交给数据库驱动程序,通过驱动程序实现对数据源的各种操作,数据库操作结果也通过驱动程序返回给应用程序。
 4.数据源
 数据源是指任一种可以通过ODBC连接的数据库管理系统,它包括要访问的数据库和数据库的运行平台。数据源名掩盖了数据库服务器或数据库文件间的差别,通过定义多个数据源,每个数据源指向一个服务器名,就可在应用程序中实现同时访问多个DBMS的目的。
 数据源(Data Source Name,简称DSN)是驱动程序与DBS连接的桥梁,数据源不是DBS,而是用于表达一个ODBC驱动程序和DBMS特殊连接的命名。在连接中,用数据源名来代表用户名、服务器名、所连接的数据库名等,可以将数据源名看成是与一个具体数据库建立的连接。
 数据源分为以下三类:  
    (1)用户数据源:用户创建的数据源,称为“用户数据源”。此时只有创建者才能使用,并且只能在所定义的机器上运行。任何用户都不能使用其他用户创建的用户数据源。
    (2)系统数据源:所有用户和在Windows NT下以服务方式运行的应用程序均可使用系统数据源。
 (3)文件数据源:文件数据源是ODBC 3.0以上版本增加的一种数据源,可用于企业用户,ODBC驱动程序也安装在用户的计算机上。
 总之,ODBC提供了在不同数据库环境中为C/S结构的客户机访问异构数据库的接口,也就是在由异构数据库服务器构成的客户机/服务器结构中,要实现对不同数据库进行的数据访问,就需要一个能连接不同的客户机平台到不同服务器的桥梁,ODBC就是起这种连接作用的桥梁。ODBC提供了一个开放的、标准的能访问从PC机、小型机到大型机数据库数据的接口。使用ODBC标准接口的应用程序,开发者可以不必深入了解要访问的数据库系统,比如其支持的操作和数据类型等信息,而只需掌握通用的ODBC API编程方法即可。使用ODBC的另一个好处是当作为数据库源的数据库服务器上的数据库管理系统升级或转换到不同的数据库管理系统时,客户机端应用程序不需作任何改变,因此利用ODBC开发的数据库应用程序具有很好的移植性。 
 9.5  ADO数据控件
 9.5.1 ADO对象模型   
    ADO(ActiveX Data Object)数据访问接口是Microsoft处理数据库信息的最新技术。它是一种ActiveX对象,采用了被称为OLE DB的数据访问模式,是数据访问对象DAO、远程数据对象RDO和开放数据库互连ODBC三种方式的扩展。ADO对象模型定义了—个可编程的分层对象集合,主要由三个对象成员Connection、Command和Recordset对象,以及几个集合对象Errors、Parameters和Fields等所组成。图9.13示意了这些对象之间的关系。表9.6是对这些对象的分工描述。

 

 

 

 

 

 

 图9.13  ADO对象模型

 表9.6 ADO对象描述
 对象名  描 述 
Connection 连接数据来源 
Command 从数据源获取所需数据的命令信息 
Recordset 所获得的一组记录组成的记录集 
Error 在访问数据时,由数据源所返回的错误信息 
Parameter 与命令对象有关的参数 
Field 包含了记录集中某个字段的信息 
 
 要想在程序中使用ADO对象,必须先为当前工程引用ADO的对象库。引用方式是执行“工程”菜单的“引用”命令,启动引用对话框,在清单中选取“Microsoft  ActiveX  Data  Objects 2.0 Library”选项。

9.5.2 使用ADO数据控件
    在使用ADO数据控件前,必须先通过“工程|部件”菜单命令选择"Microsoft ADO Data Control  6.0(OLEDB)”选项,将ADO数据控件添加到工具箱。ADO数据控件与Visual  Basic的内部Data控件很相似,它允许使用ADO数据控件的基本属性快速地创建与数据库的连接。
 1.ADO数据控件的基本属性
    (1)ConnectionString属性
    ADO控件没有DatabaseName属性,它使用ConnectionString属性与数据库建立连接。该属性包含了用于与数据源建立连接的相关信息,ConnectionString属性带有4个参数,如表9.7所示。
 (2)RecordSource属性
    RecordSource确定具体可访问的数据,这些数据构成记录集对象Recordset。该属性值可以是数据库中的单个表名,一个存储查询,也可以是使用SQL查询语言的一个查询字符串。
表9.7 ConnectionString属性参数
 参数 描述 
Provide 指定数据源的名称 
FileName 指定数据源所对应的文件名 
RemoteProvide 在远程数据服务器打开一个客户端时所用的数据源名称 
RemoteServer 在远程数据服务器打开一个主机端时所用的数据源名称 
 
   (3)ConnectionTimeout属性
 用于数据连接的超时设置,若在指定时间内连接不成功显示超时信息。
 (4)MaxRecords属性
 定义从一个查询中最多能返回的记录数。
 2. ADO数据控件的方法和事件
 ADO数据控件的方法和事件与Data控件的方法和事件完全一样。
 3.设置ADO数据控件的属性
    下面通过使用ADO数据控件连接Student.mdb数据库来说明ADO数据控件属性的设置。
    步骤1:在窗体上放置ADO数据控件,控件名采用默认名“Adodcl”。
    步骤2:单击ADO控件属性窗口中的ConnectionString属性右边的“…”按钮,弹出“属性页”对话框。在该对话框中允许通过三种不同的方式连接数据源:
    “使用连接字符串”只需要单击“生成”按钮,通过选项设置自动产生连接字符串。
    “使用Data Link文件”表示通过—个连接文件来完成。
 “使用ODBC数据资源名称”可以通过下拉式列表框,选择某个创建好的数据源名称(DSN),作为数据来源对远程数据库进行控制。
 步骤3:采用“使用连接字符串”方式连接数据源。单击“生成”按钮,打开“数据链接属性”对话框。在“提供者”选项卡内选择一个合适的OLE DB数据源,Student.mdb是Access数据库,选择“Microsoft Jet 3.51 OLE DB Provider”选项。然后单击“下—步”按钮或打开“连接”选项卡,在对话框内指定数据库文件,这里为Student.mdb。为保证连接有效,可单击“连接”选项卡右下方的“测试连接”按钮,如果测试成功则关闭ConnectionString属性页。
    步骤4:单击ADO控件属性窗口中的RecordSource属性右边的“…”按钮,弹出记录源属性页对话框。
    在“命令类型”下拉式列表框中选择“2adCmdTable”选项,在“表或存储过程名称”下拉式列表框中选择Student.mdb数据库中的“基本情况”表,关闭记录源属性页。此时,已完成了ADO数据控件的连接工作。
 由于ADO数据控件是一个ActiveX控件,也可以用鼠标右键单击ADO数据控件,在弹出的快捷菜单中选择“ADODC属性”菜单命令,打开ADO数据控件属性页对话框,一次完成步骤1~步骤4的全部设置。
 
9.5.3  ADO数据控件上新增绑定控件的使用
    随着ADO对象模型的引入,Visual Basic 6.0除了保留以往的一些绑定控件外,又提供了一些新的成员来连接不同数据类型的数据。这些新成员主要有DataGrid、DataCombo、DataList、DataReport、MSHFlexGrid、MSChart控件和MonthView等控件。这些新增绑定控件必须使用ADO数据控件进行绑定。
    Visual Basic 6.0在绑定控件上不仅对DataSource和DataField属性在连接功能上作了改进,又增加了DataMember与DataFormat属性使数据访问的队列更加完整。DataMember属性允许处理多个数据集,DataFormat属性用于指定数据内容的显示格式。
    例9.6  使用ADO数据控件和DataGrid数据网格控件浏览数据库Student.mdb,并使之具有编辑功能。
    在窗体上放置ADO数据控件,并按前面介绍的ADO数据控件属性设置过程连接数据库Student.mdb中的基本情况表。
    DataGrid控件允许用户同时浏览或修改多个记录的数据。在使用DataGrid控件前也必须先通过“工程|部件”菜单命令选择“Microsoft  DataGrid  Control 6.0(OLEDB)”选项,将DataGrid控件添加到工具箱,再将DataGrid控件放置到窗体上。设置DataGrid网格控件的DataSource属性为Adodc1,就可将DataGrid1绑定到数据控件Adodc1上。
    显示在DataGrid网格内的记录集,可以通过DataGrid控件的AllowAddNew、AllowDelete和AllowUpdate属性设置控制增,删、改操作。
    如果要改变DataGrid网格上显示的字段,可用鼠标右键单击DataGrid控件,在弹出的快捷菜单中选择“检索字段”选项。Visual Basic提示是否替换现有的网格布局,单击“是”按钮就可将表中的字段装载到DataGrid控件中。再次用鼠标右键单击DataGrid控件,在弹出的快捷菜单中选择“编辑”选项,进入数据网格字段布局的编辑状态,此时,当鼠标指在字段名上时,鼠标指针变成黑色向下箭头。用鼠标右键单击需要修改的字段名,在弹出的快捷菜单中选择“删除”选项,就可从DataGrid控件中删除该字段,也可选择“属性”选项修改字段的显示宽度或字段标题。
 图9.14所示为具有增、删、改功能的数据网格绑定。标有号的记录行表示允许增加新记录。
 
图9.14  具有增、删、改功能的数据网格绑定
9.5.4 使用数据窗体向导
 
 Visual Basic 6.0提供了一个功能强大的数据窗体向导,通过几个交互过程,便能创建前面介绍的ADO数据控件和绑定控件,构成—个访问数据的窗口。数据窗体向导属于外接程序,在使用前必须从Visual Basic 6.0集成开发环境的横向菜单中点击“外接程序”,再点击子菜单的“外接程序管理器”,从打开的“外接程序管理器”窗口选择 “VB 6数据窗体向导” 命令,将数据窗体装入到“外接程序”中。
 这里以Student.mdb数据库的基本情况表作为数据源来说明数据访问窗口建立的过程。
    例9.7  使用数据窗体向导建立Student.mdb数据库的数据访问对话框。
    步骤1:执行“外接程序”菜单中的“数据窗体向导”命令,进入“数据窗体向导-介绍”对话框,可以利用先前建立的数据窗体信息配置文件创建外观相似的数据访问窗体,选择“无”将不使用现有的配置文件。
    步骤2:单击“下—步”按钮,进入“数据窗体向导-数据库类型”对话框,可以选择任何版本的Access数据库或任何ODBC兼容的用于远程访问的数据库。本例中选择Access数据库。
    步骤3:在“数据窗体向导—数据库”对话框内选择具体的数据库文件。本例为Student.mdb数据库。
 步骤4:在“数据窗体向导—Form”对话框内设置应用窗体的工作特性。
 其中,在“窗体名称为”文本框输入将要创建的窗体名;“窗体布局”指定窗口内显示数据的类型,可以按单条记录形式显示,也可以按数据网格形式同时显示多条记录;绑定类型用于选择连接数据来源的方式,可以使用ADODC数据控件访问数据,也可以使用ADO对象程序代码访问数据。本例窗体名为frmjbqk,选“单个记录”形式,使用“ADO数据控件”访问数据。
 步骤5:在“数据窗体向导-记录源”对话框内选择所需要的数据。
    其中,“记录源”下拉式列表框用于选择数据库中的表单,本例选择“基本情况”表;窗口中间的4个箭头按钮用于选定字段,“列排序按”下拉式列表框用于选择排序依据。
 步骤6:在“数据窗体向导-控件选择”对话框内,选择所创建的数据访问窗体需要提供哪些操作按钮。
 步骤7:进入“数据窗体向导—已完成”对话框,可以将整个操作过程保存到一个向导配置文件.rwp中。
 单击“完成”按钮结束数据窗体向导的交互,此时向导将自动产生数据访问对话框的画面及代码。可以对产生的窗体布局形式进行调整或在此基础上加上其他控件对象。图9.15为调整照片位置的数据访问对话框运行结果。各按钮的程序代码不难理解,请读者自己阅读。
 
 
 图9.15  数据窗体向导创建的数据访问对话框
 
 图9.16为窗体布局(步骤4)选定网格(数据表)形式的数据访问窗口运行结果。图9.17所示为窗体布局选定主表/细表形式,以基本情况表作为主表,学生成绩表为细表所建立的数据访问窗口。图9.18为窗体布局(步骤4)选定MSHFlexGrid数据网格形式的数据访问窗口运行结果。

 
 
 图9.16  选定网格(数据表)形式                   图9.18  选定MSHFlexGrid数据网格
 
 
 图9.17   选定主表/细表形式
 
 9.6 VB中SQL的实现
 SQL中使用SELECT语句实现查询,SELECT语句基本上是数据库记录集的定义语句。Data控件的RecordSource属性不—定是数据表名,可以是数据表中的某些行或多个数据表中的数据组合。可以直接在Data控件的RecordSource属性栏中输入SQL,也可在代码中通过SQL语句将选择的记录集赋给数据控件的RecordSource属性,也可赋予对象变量。
 例9.8   将例9.5中的查找功能改用SQL语句处理,显示某专业的学生记录。
 使用SQL语句查询只要将例9.5中命令按钮Command5_Click事件写为如下代码:
Private Sub Command5_Click()
  Dim mzy As String
  mzy = InputBox$("请输入专业", "查找窗")
  Data1.RecordSource = "Select * From 基本情况 Where 专业 = '" & mzy & "'"
  Data1.Refresh
  If Data1.Recordset.EOF Then
    MsgBox "无此专业!", , "提示"
    Data1.RecordSource = "基本情况"
    Data1.Refresh
  End If
End Sub
    程序中“Select *”选择表中所有字段(也可以指定选择部分列);“From基本情况”短语指定数据来源;“Where 专业 = '" & mzy & "'"”短语构成查询条件,用于过滤表中的记录;Data1.Refresh方法激活这些变化。此时,若Data1.Recordset.EOF为True,表示记录过滤后无数据,重新打开原来的基本情况表。
 注意:代码中的两处Refresh语句不能合用为一句,这是因为在执行了Select命令后,必须激活这些变化,然后才能判断记录集内有无数据。
 也可用SQL语句实现模糊查询,命令按钮Command5_Click事件改为如下代码:
Private Sub Command5_Click()
  Dim mzy As String
  mzy = InputBox$("请输入专业", "查找窗")
  Data1.RecordSource = "Select * From 基本情况 Where 专业 like '*" & mzy & "*'"
  Data1.Refresh
  If Data1.Recordset.EOF Then
    MsgBox "无此专业!", , "提示"
    Data1.RecordSource = "基本情况"
    Data1.Refresh
  End If
End Sub
    例9.9  用SQL语句从Student.mdb数据库的两个数据表中选择数据构成记录集,并通过数据控件浏览记录集。
 在窗体上放置与例9.2类似的控件,如图9.20所示。Data控件的DatabaseName属性指定数据库Student.mdb,RecordSource属性空缺,各文本框的DataSource=Data1,DataField属性分别设置为学号、姓名、课程、成绩,而照片字段绑定图形框。
 本例要求从基本情况中选择学生的学号、姓名、照片,从学生成绩表中选择该学生的课程和成绩来构成记录集,可在Form_ Load事件中使用SQL语句,通过“Where 学生成绩表.学号=基本情况.学号”短语实现两表之间的连接,用Select命令从学生成绩表中选择课程、成绩字段,从基本情况表中选择学号、姓名和照片字段构成记录集:
Private Sub Form_Load()
  Data1.RecordSource = "Select 基本情况.学号,基本情况.姓名,基本情况.照片,学生成绩表.课程,学生成绩表.成绩 From 学生成绩表,基本情况 Where 学生成绩表.学号=基本情况.学号"
End Sub
    当窗体启动后,数据显示如图 9.19所示,数据控件上的箭头按钮可改变记录位置。如果要求显示的记录按一定的顺序排列,可使用ORDER BY子句。


 图 9.19  数据显示
 
 注意:当FROM子句列出多个表时,它们出现的顺序并不重要。Select短语中字段的排列决定了所产生的记录集内每一列数据的排列顺序。为了提高可读性可以重新排序表中的字段。
 例9.10 用SQL指令按专业统计Student.mdb数据库中各专业的人数,要求按图9.20所示形式输出。
 在窗体上放置一个Data控件和一个网格控件MSFlexGrid1。Data1的DatabaseName属性指定数据库Student.mdb,网格控件的DataSource=Data1。
 

图9.20  通过数据控件浏览记录集

    为了统计各专业的人数,需要对基本情况表内的记录按专业分组。“Group By专业”可将同一专业的记录合并成一条新记录。要记录统计结果,需要构造一个输出字段,此时可使用SQL的统计函数Count()作为输出字段,它按专业分组创建摘要值。若希望按用户要求的标题显示统计摘要值,可用As短语命名一个别名。“按专业统计人数”按钮的指令代码为:
Private Sub Command1_Click()
  Data1.RecordSource = "select 专业,count(*) as 人数 from 基本情况 group by 专业"
  Data1.Refresh
End Sub
  运行结果如图9.21。

图9.21  使用SQL的统计函数

   有时,我们只要返回一定数量的记录,如获取平均成绩最好的前5名,则“按平均成绩统计前5名” 按钮的指令代码为:
Private Sub Command2_Click()
   Data1.RecordSource = "select top 5 学号,avg(成绩) as 平均成绩 from  学生成绩表 group by 学号 order by avg(成绩) desc"
  Data1.Refresh
End Sub
 这里,“Group by 学号”短语将同一学生的各门课程的记录合并成一条记录,由Avg(成绩)计算出该学生的平均成绩,“Order By Avg(成绩) Desc”短语按平均成绩的降序排列数据,“Top 5”短语返回最前面的5条记录。如果不包括ORDER BY子句,查询将从学生成绩表中返回随机的5条记录。“恢复原表内容”按钮的指令代码为:
Private Sub Command3_Click()
 Data1.RecordSource = "基本情况"
 Data1.Refresh
End Sub
 以上介绍的是在Data控件上使用SQL,如果要在ADO数据控件上使用SQL语句,最好通过代码配合ADO数据控件完成数据库的连接,这可给程序带来更大的灵活性。
 例9.11  我们将例9.9中的Data控件改用ADO数据控件,用SQL语句从Student.mdb数据库的两个数据表中选择数据构成记录集。
    将Data控件改用ADO数据控件Adodc1,各文本框的Datasource=Adodc1,DataField属性分别设置为学号、姓名、课程、成绩,而字段照片绑定图形框。
 ADO数据控件的ConnectionString属性设置为与数据源连接的相关信息,通过操作完成与student.mdb的数据连接(此时,可查看到ConnectionString属性的内容);DataSource指定连接的数据库文件名,如图9.22。

 图9.22  使用ADO数据控件
 
 即DataSource属性使用SQL语句:
 select  学生成绩表.*,基本情况.姓名,基本情况.照片 from 学生成绩表,基本情况 where 学生成绩表.学号=基本情况.学号
 程序执行后将产生与图9.22所示相同的效果。
 例9.12  设计一个窗体,计算Student.mdb数据库内学生成绩表中每个学生的平均成绩,产生姓名、平均成绩和最低成绩三项数据,按平均成绩降序排列数据,并用该数据作图。
    学生成绩表中没有平均成绩和最低成绩这两项数据,可以在SELECT子句内使用统计函数AVG()和Min()产生,“Group  By学号”可将同一学生的记录合并成一条新记录。学生成绩表中没有姓名字段,故需要通过条件“基本情况.学号=学生成绩表.学号”从基本情况表取得。然后,将产生的记录集连接到ADO数据控件上。
    要显示作图数据,可在窗体上放置一个网格控件(选择工程→部件中Microsoft Data Grid Control 6.0 (OLEDB)),设置网格的DataSource=Adodcl,将其绑定到ADO数据控件上。此例将Adodc1控件的Visible属性设为False,故在图9.22中看不到Adodc1控件。
    要绘制图表,可使用绑定控件MsChart。MsChart控件也是一个Active X控件,需要通过“工程→部件”菜单命令,将MsChart控件添加到工具箱中。要将作图数据传送到Mschart控件,只需要设置MsChart1.DataSource=Adodc1。如果只要选择部分数据作图,可以将作图数据存入到数组,再设置MsChart1.Data=数组名即可。
     将Adodcl的RecordSource属性设置为SQL语句,代码如下:
”select  基本情况.姓名,avg(成绩) as 平均成绩,min(成绩) as 最低成绩 from 学生成绩表,基本情况 where 学生成绩表.学号=基本情况.学号 group by 学生成绩表.学号,基本情况.姓名 order by avg(成绩) desc”
 程序执行后将产生图9.23所示的效果。

图9.23   显示作图数据

 9.7  VB中使用ODBC
 在VB环境开发数据库应用时,与数据库连接和对数据库的数据操作是通过ODBC、Microsoft Jet(数据库引擎)等实现的。Microsoft Jet主要用于本地数据库,而在C/S结构的应用中一般用ODBC。
 例9.13  使用ADO数据控件,设计一个简单窗体,用来扫描student.mdb数据库的基本情况表。窗体中几个约束数据文本框绑定到连接表中当前记录的ADO数据控件。这个项目不需编程,步骤如下:
 步骤1:开始新项目,并在项目工具箱中加进ADO数据控件。
    步骤2:在窗体上放一个ADO数据控件的实例。
    步骤3:右键单击控件,并从弹出菜单中选择“ADODC属性”命令(或单击Adodc1的ConnectionString属性旁的“…”按钮),打开ADO数据控件的属性页。
    步骤4:选择“通用”标签,并选择“使用ODBC数据资源名称”单选项。
    步骤5:现在要指定数据源(ADO数据控件联系的数据库)。可以看出,可以指定多种数据库,但应用程序用相同的方法处理。不管实际提供表格的数据库为何种形式,它用相同的语句访问表格及其记录。
    数据源名就是系统知道的数据库名。数据源名只要生成一次,此后任何应用程序都可以使用。如果系统上没有数据源名,则按下列步骤生成新的数据源名:
    1.单击“新建”按钮,打开“创建新数据源”窗口。在这个窗口中可以选择数据源类型,选项包括:
    文件数据源   所有用户均可以访问的数据库文件。
    用户数据源   只有你能访问的数据库文件。
    系统数据源   能登录该机器的任何用户都能访问的数据库文件。
    2.选择“系统数据源”,以便从网上登录测试锁定机制(如果在网络环境中)。
    3.单击“下一步”按钮显示“创建新数据源”窗口,指定访问数据库所用的驱动程序。   
 驱动程序必须符合数据库。可以看出,数据源可以是个大数据库,包括Access、Oracle、 SQL Server。本例采用Access数据库。
    4.选择Microsoft Access Driver,并单击“下一步”按钮。
    新窗口指出,已选择了系统数据源并用Access驱动程序访问。
    5.单击“完成”按钮,生成数据源。
    这时就可以指定将哪个Access数据库赋予新建的数据源。在出现的“ODBC Microsoft Access 安装”窗口中,执行如下操作步骤:
    6.在第一个框中,指定数据源名mystudent,在“描述”框中,输入简短说明:student数据源(说明可以空缺)。
    7.单击“选择”按钮,并通过“选定数据库”窗口选择数据库,找到VB98文件夹中的student.mdb(假设student.mdb存放在此)。
    8.回到ADO数据控件的属性页时,新的数据源即会出现在“使用ODBC数据资源名称”下拉清单中。
 步骤6:展开下拉清单,并选择mystudent数据源。
 实际上,这就指定了要使用的数据库(类似于设计Data控件的DatabaseName属性)。
 下一个任务是,选择ADO数据控件能看到的数据库记录(表格或SQL语句返回的记录集)。
    步骤7:切换到“记录源”标签(或单击Adodc1的RecordSource属性旁的“…”按钮)。
    步骤8:在“命令类型” 下拉清单中,选择adCmdTable项目,这是记录源的类型。
    步骤9:在“表或存储过程名称”下拉的清单中出现数据库中的所有表名。选择基本情况表。
    Adodc1控件的RecordSource属性栏中出现student.mdb数据库的基本情况表。
 步骤10:将四个文本框控件和四个标题控件放在窗体上。将它们的DataSource=Adodc1,DataField分别设置为学号、姓名、专业、出生年月。
   Mystudent数据源已经注册到系统上,不必再次生成。它会自动出现在ADO数据控件属性页的“使用ODBC数据资源名称”下拉清单中。
   运行结果如图9.24。

图9.24  使用ADO数据控件及ODBC

 例9.14  ADO数据控件使用自己的高级约束数据控件,即DataList和DataCombo控件。
 本例要求在DataList控件中显示学号,要将DataList控件与ADO数据控件连接,使用户每次选择清单中的新学号,窗体上的文本框中出现相应的字段。
 要使用DataList和DataCombo控件,首先要将其加进工具箱。步骤如下:
    1.选择“工程|部件”菜单,打开“部件”对话框,选取“Microsoft DataList Controls 6.0(OLEDB)”复选项。
    2.将DataList控件的实例放在窗体上。
    3.要用基本情况表中的学号建立DataList控件,设置属性RowSource= Adodc1,ListField=学号。
    如果这时运行应用程序,则会自动生成DataList控件,但清单中所选的学号对约束数据控件没有影响。我们要加入一些代码,在清单中每次选择另一学号时,移动ADO数据控件,具体方法如下:
Private Sub DataList1_Click()
  Adodc1.Recordset.Bookmark = DataList1.SelectedItem
End Sub
    每次单击清单中的新项目时,这个项目就成为ADO数据控件的书签。
 大多数情况下,用于自动建立DataList控件的数据通常没有排序。如果DataList控件中学号没有排序,就无法方便地找到清单中的项目。要使DataList控件中学号排序,按如下步骤修改ADO数据控件的RecordSource属性:
    1.设计图9.25所示的窗体。
    2.右键单击Adodc1控件,并在属性页中将“ODBC 数据源名”设置为mystudent。
    3.切换到“记录源” 标签,指定SQL 语               图9.25  Adodc1控件
句而不是表格:将“命令类型”设置为    adCmdUnknown,并在“命令文本”框中输人下列SQL语句:
    select * from 基本情况  order by 学号
 例9.15  用外接程序的数据窗体向导创建主细表(数据库student.mdb中的主表是基本情况表,细表是学生成绩表)。
 步骤1:选择 “外接程序”的“数据窗体向导”菜单(如菜单中无此选项,可通过“外接程序”的“外接程序管理器”加载“VB 6 数据窗体向导”),出现“数据窗体向导——介绍”窗口,选择“无”,单击下一步;
 步骤2: 在“数据窗体向导——数据库类型”窗口“选择Remote(ODBC)”,单击下一步;
 步骤3: 在“数据窗体向导——连接信息”窗口,在DSN(数据源名)栏选择已定义的数据源mystudent,单击下一步;
 步骤4: 在“数据窗体向导—Form”窗口,在“窗体名称为”文本框中输入窗体名称,本例输入frm_jbqk;窗体布局选择“主表/细表”,单击下一步;
 步骤5: 在“数据窗体向导—主表记录源”窗口选择主表及其字段,本例在“记录源” 文本框选择主表为“基本情况”,在“可用字段”中挑选字段学号、姓名、专业到“选定字段”,单击下一步;
 步骤6:在“数据窗体向导—详细资料记录源”窗口选择细表及其字段,本例在“记录源” 文本框选择细表为“学生成绩表”,在“可用字段”中挑选字段学号、课程、成绩到“选定字段”,单击下一步;
 步骤7:在“ 数据窗体向导—记录源关系”窗口,选择主表及其细表相连接的字段,本例在“主表”和“细表”下拉列表框中均选择“学号”,单击下一步;
 步骤8:在“ 数据窗体向导—控件选择”窗口选择需要的控件,单击下一步;  
 步骤9:单击“完成”按钮。运行程序结果如图9.26所示。

图9.26 用外接程序的数据窗体向导创建主细表
 
 习题与思考题
 
 9.1 选择题
 1.要利用数据控件返回数据库中记录集,则需设置_______属性。
(A)Connect    (B)DatabaseName     (C)RecordSource    (D)RecordType
 2.Seek方法可在______记录集中进行查找。
(A)Table类型  (B)Snapshot类型    (C)Dynaset类型     (D)以上三者
 3.下列_________组关键字是Select语句中不可缺少的。
(A)Select 、From  (B)Select、Where  (C)From、Order By  (D)Select、All
 4.在使用Delete方法删除当前记录后,记录指针位于____________。
被删除记录上           (B)被删除记录的上一条 
(C)被删除记录下一条       (D)记录集的第一条
 5.使用ADO数据控件的ConnectionString属性与数据源建立连接相关信息,在属性页对话框中可以有_________种不同的连接方式。
 (A)1     (B)2      (C)3        (D)4
 6.数据绑定列表框DBList和下拉式列表框DBCombo控件中的列表数据通过属性_________从数据库中获得。
DataSource和DataField            (B)RowSource和ListField
(C)BoundColumn和BoundText       (D)DataSource和ListField
 7.DBList控件和DBCombo控件与数据库的绑定通过属性_________实现。
DataSource和DataField           (B)RowSource和ListField
(C)BoundColumn和BoundText      (D)DataSource和ListField
 8.下列所显示的字符串中,字符串__________不包含在ADO数据控件的ConnectionString属性中。
Microsoft Jet 3.51 OLE DB Provider
Data Source=C:\Mydb.mdb
Persist Security Info=False
2-adCmdTable0
 9.2 填空题
 1.要使绑定控件能通过数据控件Data1连接到数据库上,必须设置控件的_____属性为______,要使绑定控件能与有效的字段建立联系,则须设置控件的_____属性。
 2.如果数据控件连接的是单表数据库,则_______属性应设置为数据库文件所在的子文件夹名,而具体文件名放在______属性中。
 3.记录集的RecordCount属性用于对Recordset对象中的记录计数,为了获得准确值,应先使用_______方法,再获得RecordCount属性值。
 4.要在程序中通过代码使用ADO对象,必须先为当前工程引用__________。
 9.3 问答题
 1.记录、字段、表与数据库之间的关系是什么?
 2.Visual Basic中记录集有几种类型?有何区别?
 3.要利用数据控件返回数据库中记录的集合,怎样设置它的属性?
 4.对数据库进行增、改操作后必须使用什么方法确认操作?
 5.怎样使绑定控件能被数据库约束?
 6.怎样准确地获得记录集的记录计数?
 7.ODBC技术与传统的数据库编程方式有什么区别?
 8.什么是ODBC数据源?有哪三类?