Visual FoxPro 6.0数据库与程序设计
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

第3章 Visual FoxPro 6.0数据库及其操作

本书将从创建项目开始,循序渐进地介绍数据库、数据表、查询和视图、表单和报表等对象的建立和使用,最终生成一个可在Windows环境下直接运行的应用程序。整个内容以项目管理器为主要工作平台,结合菜单和命令两种操作方式来介绍VFP的基本应用。

本章主要学习VFP数据库的基本概念和基本操作,它是开发数据库应用系统的基础。

3.1 项目的创建

在VFP中,项目是文件、数据、文档和VFP对象的集合,它包含了一个应用系统开发过程中使用的各种数据库、表、查询、表单、报表、应用程序及其他所有文件。利用“项目管理器”可以很方便地组织和管理项目中的各类数据和对象,创建一个扩展名为.PJX的项目文件。用户在开发一个应用系统时,通常都是先从创建项目开始的。

1.工作目录的建立

根据复杂程度,一个数据库应用系统可能会有几十个、甚至上百个各种类型的文件,如数据库文件、表文件、表单文件、查询文件、应用程序文件等。利用项目管理器可以在逻辑上将这些文件集合成一个有机的整体,形成一个项目文件;项目文件中保存的只是对这些文件的引用,文件在磁盘中的实际存储位置则由用户指定。因此,为了有效地组织和管理磁盘中的这些文件,用户应该建立自己的工作目录,将开发应用系统时创建的不同类型的文件存放在磁盘的相应文件夹中,如将所有的表文件存放在名为“数据”的文件夹中,将所有的表单文件存放在名为“表单”的文件夹中。

本书以开发教学管理数据库为例,创建所需的各种文件,并将它们统一保存在设定的工作目录中。为此,首先利用资源管理器,在E盘的根目录下新建一个名为“VFP6”的文件夹作为工作目录。该文件夹可以设置为默认目录,以便在VFP中保存新建的文件时,系统自动选择该文件夹,设置默认目录的方法见1.5节。

2.项目文件的建立

创建项目文件可以使用菜单或命令两种方式。

(1)菜单方式

① 选择“文件|新建”命令(或单击常用工具栏中的“新建”按钮)打开图3.1(a)所示的“新建”对话框。

② 在“文件类型”栏中选择“项目”选项,然后单击“新建文件”按钮,出现图3.1(b)所示的“创建”对话框。

③ 选择存储路径为“E:\VFP6”,并输入项目文件名“教学.pjx”(系统将文件类型默认为项目,扩展名.PJX可以省略),然后单击“保存”按钮。

(2)命令方式

格式:CREATE PROJECT [<项目文件名>]

功能:打开项目管理器创建项目。

说明:

① <项目文件名>中应包含存储路径,否则文件将存放在默认目录下。如没有设置默认目录,则系统默认保存在“C:\Program Files\Microsoft Visual Studio\Vfp98”文件夹中(假设VFP6.0安装在C盘)。

② 如命令中不带<项目文件名>,系统将弹出一个如图3.1(b)所示的“创建”对话框,让用户输入新建的项目文件名。

图3.1 新建项目文件

【例3.1】 用命令方式创建“教学”项目文件。

        CREATE PROJECT E:\VFP6\教学.PJX   &&CREA PROJ E:\VFP6\教学.PJX等同左侧命令行

使用上述两种方法都可以在“E:\VFP6”中建立一个名为“教学”的项目文件,同时系统启动项目管理器,并在菜单栏中出现“项目”菜单。

单击项目管理器窗口右上角的“关闭”按钮可以关闭项目。当关闭一个空项目文件(即项目中未包含任何文件)时,会显示一个如图3.2所示的提示框。单击“删除”按钮,系统将从磁盘上删除该空项目文件;单击“保持”按钮,系统将保存该空项目文件。

图3.2 关闭空项目文件时的提示对话框

3.项目文件的打开

在VFP中可以随时打开一个已有的项目进行操作。

(1)菜单方式

① 选择“文件|打开”命令(或单击常用工具栏中的“打开”按钮)打开图3.3所示的“打开”对话框。

② 在“文件类型”下拉框中选择“项目”选项,在“搜寻”框中选择项目所在的文件夹。

③ 双击要打开的项目文件,或者选中后再单击“确定”按钮,打开该项目。

(2)命令方式

格式:MODIFY PROJECT [<项目文件名>]

功能:打开项目管理器,显示指定的项目文件。

说明:如命令中不带<项目文件名>,系统将弹出一个如图3.3所示的“打开”对话框,让用户选择要打开的项目文件。

图3.3 “打开”对话框

【例3.2】 用命令方式打开“教学”项目文件。

        MODIFY PROJECT E:\VFP6\教学.PJX

3.2 数据库的创建及基本操作

在VFP中,数据库不再是以往xBASE数据库系统中单纯的二维表结构的概念,它是表的集合,即在一个数据库中可以包含若干个通过关键字段相互关联的二维表。例如,在教学管理数据库中可以包含学生表、课程表和成绩表等。在VFP中,数据库是以.DBC为扩展名的一种数据格式文件,它存储了所包含的表与表之间的联系,以及依赖于表的视图、联接和存储过程等信息。数据库使得对数据的管理更加方便和有效。

3.2.1 数据库的设计思想

开发数据库应用系统的首要任务之一就是设计一个结构合理的数据库,它不仅能存储所需要的实体信息,而且能正确反映出实体之间的联系,以便方便、快速地访问所需要的信息,并得到准确的结果。

1. 设计步骤

对一个数据库而言,如数据组织得当,就能把数据库设计得相当灵活,使系统可以用多种方法组合或提供信息。

要增强数据库的灵活性,一个重要的原则就是尽可能将信息拆分入表,即避免设计大而杂的表。因此,首先要分离那些需要作为单个主题而独立保存的信息,然后告诉VFP这些主题之间有何关系,以便在需要时把正确的信息组合在一起。通过将不同的信息分散在不同的表中,可以使数据的组织工作和维护工作更简单,同时也容易保证建立的应用程序具有较高的性能。

以教学管理系统为例,它涉及学生、课程以及学生所学课程的成绩等信息,在设计相应的数据库时,就应当把学生信息保存到“学生”表中,把相关课程的信息保存到“课程”表中,把学生所学课程的成绩信息保存到“成绩”表中。

以下是数据库设计的一般步骤:

(1)分析数据需求,确定数据库要存储哪些信息。

(2)确定需要的表。在明确了建立数据库的目的之后,就可以将所需信息划分成各个独立且彼此相关的主题,并在数据库中为每个主题建立一个表。

(3)确定所需字段,实际上就是确定每个表中要存储的信息,即确定各表的结构。例如,在学生表中,可以有学号、姓名、系别等字段。

(4)确定关系。分析每个表,确定各表之间的数据应该如何联接。必要时,可在表中加入字段或创建一个新表来明确关系。

(5)改进设计。对设计方案进一步分析,查找其中的错误,调整设计。

在最初的设计中,难免会出现错误或遗漏。VFP很容易在创建数据库时对原设计方案进行修改。但一旦在数据库中输入了大量数据,并且用到报表、表单或是应用程序中之后,再进行修改就比较困难了。所以,在初步确定设计方案后,一定要做适量的测试、分析工作,排除其中错误和不合理的地方,不断完善数据库设计,在连编项目生成应用程序之前,确保设计方案合理、可靠。

2. 设计过程

按照上述步骤,以构建教学管理数据库为例,设计过程如下:

(1)明确设计目的 一方面要弄清用户需求,通过与数据库的使用者反复交换意见,推敲数据库需要回答哪些问题,以确定数据库中要建立的表,以及每个表中要保存的信息;另一方面,还要充分考虑到数据库可能的扩充和改变,以提高数据库的灵活性。

对于教学管理数据库,首先需要明确建立该数据库的目的是为了管理和方便获取与教学有关的信息,因此要收集教与学两方面的信息,如学生情况、教师情况、课程安排、考试成绩等。

(2)确定需要的表 确定数据库中的表是数据库设计过程中技巧性最强的一步。虽然在步骤(1)中根据用户想从数据库中得到的结果(包括要打印的报表、要使用的表单等),确定了需要数据库解决的问题。但对于表的结构、表与表之间的关系,还需要设计人员通过分析、归纳来确定,然后将需要的信息分门别类地加入到相应的表中。也就是说,在设计数据库时,应将不同主题的信息存储在不同的表中。

根据上面提出的教学管理数据库的要求,考虑这个数据库需要哪些表。例如,为了得到学生和课程的信息,应该为学生和课程各建一个表,把这两个表分别叫做“学生”表和“课程”表,存放有关学生和课程的基本信息。

(3)确定表中需要的字段 表是由多个记录组成的,而每个记录又是由多个字段值构成的。在确定了所需表之后,接下来应根据每个表中需要存储的信息确定该表需要的字段,这些字段既包括描述主题信息的字段,又包括建立关系的主关键字字段。

为了保证数据不重复且不遗漏信息,在确定各表字段时应注意以下几点:

① 每个字段直接和表的主题相关,描述不同主题的字段应属于不同的表。表中不应有与表内容无关的数据,确保一个表中的每个字段直接描述该表的主题。例如,在“成绩”表中不需要学生年龄的信息,该表中就不应包含“出生日期”字段。另外,如多个表中重复同样的信息,则表明在某些表中有不必要的字段。

② 字段必须是原始数据,通常不必把那些可以由其他字段推导或计算得到的数据存储在表中。一方面,这些数据可以通过原始数据计算出来;另一方面,可以防止对表中数据做修改时出现错误。例如,只要知道学生的“出生日期”就可计算出年龄,因此无须设置“年龄”字段,这样既可以节省数据库中存储数据的空间,同时也减少了出错的可能性。

③ 收集所需的全部信息,确保所需的数据信息都包括在所设计的表中,或者可由这些表中的数据计算出来。

④ 以最小的逻辑单位存储信息。表中的一个字段必须是基本的数据元素,不能包含多项信息,否则以后获取单独的信息就会很困难,应尽量把信息分解成比较小的逻辑单位。例如,在学生表中,应将学生的学号、姓名、性别等设置为不同的字段。

⑤ 使用主关键字段。为了使VFP这样的关系型数据库管理系统,能够迅速查找存储在多个独立表中的信息并组合这些信息,要求数据库的每个表都必须有一个或一组字段可用来唯一确定存储在表中的每个记录,这样的信息称为表的主关键字。例如,在学生表中,可以使用“学号”字段作为主关键字;考虑到可能存在姓名相同的情况,因此不要使用“姓名”字段作为主关键字。

VFP利用主关键字迅速关联多个表中的数据,并把数据组合在一起。

注意:

① 主关键字段名不要太长,以方便记忆和输入,且字段中不能有重复值或空值;

② 存储字段值的字段宽度取能满足要求的最小长度,以提高数据库的操作速度。

(4)确定表间关系 通过前面的操作,已经把数据分配到各个表中,并在每个表中存储了各自的数据。但是,这些表是孤立的,还需要在这些表之间定义关系。VFP将利用这些关系把各表中的内容重新组合,得到有意义的信息。

数据表之间的关系一般分为三种:一对一关系、一对多关系和多对多关系。

① 一对一关系 指A表的一个记录在B表中只能对应一个记录;反之,B表中的一个记录在A表中也只能有一个记录与之对应。

这种关系不经常使用,因为在许多情况下,这两个表的信息可以简单地合并成一个表。

② 一对多关系 指A表的一个记录在B表中对应多个记录,而B表的一个记录在A表中只有一个记录与之对应。它是关系型数据库中最普通的关系。

③ 多对多关系 指A表的一个记录在B表中可以对应多个记录,而B表的一个记录在A表中也可以对应多个记录。这种情况下,需改变数据库的设计,将多对多关系分解成两个一对多关系。方法就是在具有多对多关系的两个表之间创建称为“纽带表”的第3个表。

在教学管理数据库中,“学生”表和“课程”表之间是多对多的关系,即一门课程可以有多个学生选修,而一个学生也可以选修多门课程。通过 “成绩”表这个纽带表,可以将这种多对多关系分解成两个一对多关系。例如,通过“学生”表和“成绩”表,可以查出一个学生各门课程的成绩;而通过“课程”表和“成绩”表,可以查出某门课程都有哪些学生选修,以及这门课程的考试成绩等信息。

(5)设计优化 在初步确定了数据库需要包含哪些表、每个表包含哪些字段,以及各个表之间的关系以后,还要重新研究设计方案,检查可能存在的缺陷,例如:

① 是否遗忘了必需的字段?是否有需要的信息没有包括进去?如果是,它们是否属于已创建的表?如不属于已创建表的范围,那就需要另外创建一个表。

② 是否为每个表选择了合适的主关键字?在使用这个主关键字查找具体记录时,它是否很容易记忆和输入?要确保主关键字段的值的唯一性,绝对不会出现重复。

③ 是否在某个表中重复输入了同样的信息?如果是,需要将该表分成两个一对多关系的表。

④ 是否有字段很多而记录项很少的表,而且许多记录中的字段值为空?如果有,需要考虑重新设计该表,使它的字段减少,记录增多。

只有通过反复修改,才能设计出一个完善的数据库系统。

3.2.2 数据库的创建

1. 数据库的建立

完成数据库的设计之后,就可以进行数据库的创建工作了。建立数据库的一般方法有:

(1)在项目管理器中建立数据库

① 打开“教学.PJX”项目文件,启动项目管理器。

② 选择“数据”选项卡中的“数据库”项,单击“新建”按钮,出现图3.4所示的“新建数据库”对话框。

图3.4 “新建数据库”对话框

③ 单击“新建数据库”按钮,出现“创建”对话框,选择文件保存位置“E:\VFP6”并输入数据库名“教学管理.DBC”,然后单击“保存”按钮。

这样,就在“教学”项目中建立了一个“教学管理”数据库(该数据库文件保存在“E:\VFP6”文件夹中),同时系统打开数据库设计器和相应的“数据库设计器”工具栏(如图3.5所示),并在主窗口的菜单栏中显示“数据库”菜单项。

图3.5 数据库设计器

在创建数据库的同时,系统也建立了表、本地视图、远程视图、联接和存储等5种不同格式的文件类型,如图3.6所示。在添加任何表和其他对象之前,它是一个空数据库。

图3.6 建立“教学管理”数据库

(2)菜单方式

选择“文件|新建”命令(或单击常用工具栏中的“新建”按钮)打开“新建”对话框。选择“数据库”文件类型,然后单击“新建文件”按钮。后面的操作与在项目管理器中建立数据库的方法相同。

(3)命令方式

格式:CREATE DATABASE [<数据库文件名>]

功能:创建指定的数据库文件。

【例3.3】 用命令方式创建“教学管理”数据库文件。

      CREATE DATABASE E:\VFP6\教学管理.DBC

数据库创建之后,其名称会显示在常用工具栏的数据库下拉列表框中。

VFP系统在创建数据库时,除了在磁盘上生成一个扩展名为.BDC的数据库文件,还会自动建立与之相关的一个扩展名为.DCT的数据库备注文件,以及一个扩展名为.DCX的数据库索引文件,这3个文件的主文件名相同。备注文件和索引文件是供VFP数据库管理系统管理数据库使用的,用户一般不能直接使用它们。

虽然用上述3种方法都可以在磁盘上建立一个数据库文件,但它们还是有区别的:在项目管理器中建立的数据库在逻辑上自动包含在该项目中,而用菜单或命令方式建立的数据库不会自动包含在项目中。不仅对于数据库文件如此,对于任何其他文件(如后面要介绍的表文件、查询文件等)也是这样。

所以,在项目管理器中新建的对象会自动包含在该项目中,而用“文件”菜单中的“新建”命令或命令语句创建的对象不属于任何项目,但可以通过项目管理器中的“添加”命令添加到项目中。

2. 在项目中添加数据库

数据库创建成功后,如它还不属于项目,可以把它添加到项目中,具体操作是:

(1)打开需要添加数据库的项目文件,启动项目管理器。选定“数据库”项,单击“添加”按钮,出现“打开”对话框。

(2)在对话框中选择需要添加的数据库文件,单击“确定”按钮,该数据库即添加到当前项目中。

3.2.3 数据库的基本操作——打开、关闭与删除

1. 数据库的打开

使用数据库前,必须先打开。打开的方法一般有3种:

(1)项目管理器方式

如数据库属于一个项目,可以在项目管理器中选定要打开的数据库,然后单击“打开”按钮。双击数据库文件,或者选定数据库后单击“修改”按钮,可打开相应的数据库设计器。

(2)菜单方式

选择“文件|打开”命令,在“打开”对话框中选择“数据库”文件类型及文件存储位置,然后双击要打开的数据库文件,相应的数据库设计器也同时打开。

(3)命令方式

① 打开数据库文件

格式:OPEN DATABASE [<数据库文件名>]

② 打开数据库文件所对应的数据库设计器

格式:MODIFY DATABASE [<数据库文件名>]

【例3.4】 用命令方式打开“教学管理”数据库文件。

        OPEN  DATABASE  E:\VFP6\教学管理

2. 数据库的关闭

(1)在项目管理器中,选定需要关闭的数据库文件,然后单击“关闭”按钮。如要关闭数据库设计器,只要单击数据库设计器窗口右上角的“关闭”按钮即可。

(2)命令方式

格式:CLOSE DATABASES [ALL]

说明:不带ALL选项,只关闭当前数据库文件;带ALL选项,将关闭所有打开的数据库文件及其他所有类型的文件。

3. 数据库的删除

(1)在项目管理器中,选定需要删除的数据库文件,单击“移去”按钮,出现提示对话框:选择“移去”按钮,将从项目中移去选定的数据库文件;选择“删除”按钮,则选定的数据库文件从磁盘上被删除(物理删除)。

(2)命令方式

格式:DELETE DATABASE <数据库文件名> [DELETE TABLES]

说明:如带DELETE TABLES选项,则数据库中所有的表将被一起从磁盘上删除(物理删除);如无此选项,则只删除数据库,而原数据库中的那些表依然存在,且这些表都变成了自由表(有关数据库表和自由表的概念将在3.3.1节中介绍)。

3.3 数据表的创建

3.3.1 基本概念

1. 数据表和数据库

在VFP中,表(TABLE)是收集和存储信息的基本单元,所有的工作都是在数据表的基础上进行的。数据库(DATABASE)只是表的集合,它控制这些表协同工作,共同完成某项任务。因此,VFP中的表和库是两个不同的概念。

2. 数据表的类型

在VFP中,根据表是否属于数据库,可以把表分为两类:

(1)数据库表 属于某一数据库的表称为“数据库表”。

(2)自由表 不属于任何数据库而独立存在的表称为“自由表”。

数据库表和自由表相比,具有一些自由表所没有的属性,如长字段名、主关键字、触发器、默认值、表关系等。在设计应用程序时,如要让多个数据库共享一些信息,应将这些信息放入自由表;或者将自由表移入某一数据库,以便和该数据库中的其他表协同工作。

数据库表和自由表可以相互转换。当把自由表加入到数据库中时,自由表就变成了数据库表,同时具有数据库表的某些属性;反之,当将数据库表从数据库中移去时,数据库表就变成自由表,原来所具有的数据库表的某些属性也同时消失。

此外,在VFP中,任何一个数据表都只能属于一个数据库。如要将一个数据库中的表移到其他数据库,必须先将该数据库表变为自由表,再将其加入到另一数据库中。

3. 数据表的结构

一个数据表,无论是数据库表还是自由表,在形式上都是一个二维表结构,表文件以.DBF为扩展名存储在磁盘上。

表中的每一列称为一个字段,每一行称为一条记录。确定表中的字段,主要是为每个字段指定名称、数据类型和宽度,这些信息决定了数据在表中是如何被标识和保存。

(1)字段名 字段名必须以字母或汉字开头,由字母、汉字、数字或下划线组成,不能包含空格,且字段名应尽量与内容相关。自由表字段名最长为10字节,数据库表字段名最长为128字节。

注意:常见的汉字属基本集,一个汉字占2字节;扩充集上一个汉字占4字节。

(2)字段类型 字段的数据类型决定了存储在字段中的值的数据类型,共有13种,分别是字符型(C)、货币型(Y)、数值型(N)、浮点型(F)、日期型(D)、日期时间型(T)、双精度型(B)、整型(I)、逻辑型(L)、备注型(M)、通用型(G)、二进制字符型和二进制备注型。

字段的数据类型应与将要存储在其中的信息类型相匹配;确定了字段的数据类型,也就决定了对该字段所允许的操作。

(3)字段宽度 字段宽度必须能够容纳将要显示的信息内容,字符型字段宽度不得大于254字节,否则需用备注型字段存储。浮点型和数值型字段的宽度为整数位和小数位的和再加1(小数点占一位),最多20位,在内存中占8字节。

其他几个类型的字段宽度由系统规定:逻辑型字段宽度为1字节;日期型、日期时间型、货币型、双精度数据型字段宽度为8字节;备注型、通用型、整数型以及二进制备注型字段宽度为4字节;二进制字符型字段宽度为1~254字节。

(4)小数位 若字段的类型是数值型和浮点型,还需给出小数位数,若是整数,小数位为0。小数点与小数位数的长度都属于总长的一部分,在VFP中,小数位数不能大于9;双精度型数据的小数位数不能大于18。

(5)使用空值 在建立数据表时,可以指定字段是否接受空值(NULL)。它不同于零、空字符串或者空白,而是一个不存在的值。当数据表中某个记录的某个字段内容无法知道确切信息时,可以先赋予NULL值,等内容明确之后,再存入有实际意义的信息。

VFP系统提供了“表向导”和“表设计器”两种可视化工具来创建表结构,本章主要介绍“表设计器”的用法。定义好表结构以后就可以向表中输入数据,即给每个字段赋值了。因此,一个完整的表是由表结构和表记录两部分构成的。

在下面的设计中,将用到教学管理数据库中的“学生”、“课程”和“成绩”3个表,其结构和内容如表3-1至表3-6所示。

表3.1 “学生”表结构

表3.2 “课程”表结构

表3.4 “学生”表

表3.5 “课程”表

表3.6 “成绩”表

3.3.2 自由表的建立

自由表是尚未属于任何数据库的表,所以不在VFP中创建xBASE的.DBF文件都是自由表。在VFP中创建表时,如当前没有打开数据库,则创建的表也是自由表。下面以“学生”表为例,建立自由表。

1. 表结构的定义

利用表设计器可以很方便地创建表的结构。打开表设计器一般有3种方法:

(1)菜单方式

① 选择“文件|新建”命令(或单击常用工具栏中的“新建”按钮)打开“新建”对话框。选择“表”文件类型,单击“新建文件”按钮,打开“创建”对话框。

② 在对话框中,选择保存位置“E:\VFP6\DATA”(为便于管理各类型文件,在E:\VFP6目录下再建一个名为DATA的子文件夹,用来存放所有的表文件),输入表文件名“学生.DBF”,然后单击“保存”按钮。

(2)命令方式

格式:CREATE <表文件名> && 这里的表文件名为“学生.DBF”,其扩展名可省略

功能:打开表设计器,创建数据表。

(3)项目管理器方式

在项目管理器中,从“数据”选项卡选择“自由表”,单击“新建”命令。用这种方法创建的自由表属于一个项目。

用上述三种方法都可打开表设计器,如图3.7所示,选择“字段”选项卡。

图3.7 表设计器

① 在“字段名”栏中输入字段的名称。

② 在“类型”栏中,单击列表框右边的箭头按钮,从列表中选择一种字段类型。

③ 在“宽度”栏中,输入或设置以字节为单位的宽度。一般汉字属基本集,1个汉字占2字节,而扩充集上的汉字占4字节,字段的宽度应足够容纳将要存储的信息内容。

④ 对于数值型字段,还要设置“小数位数”栏中的小数位数(不含小数点本身)。

⑤ 如允许字段接受空值,则选中“NULL”。使用NULL值表明记录中该字段的信息目前还无法得到或确定,而不是零、空字符串或空白。

字段名前的双向箭头表示该行为当前行,一行内的各项目之间可按Tab键移动。

按表3.1给出的“学生”表结构,分别定义各字段,如图3.7所示。

图3.8 输入记录提示框

在表设计器中定义好各个字段之后,单击“确定”按钮,就完成了表结构的创建。此时会出现图3.8所示的提示框,询问“现在输入数据记录吗?”。选择“是”按钮,则可立即开始输入记录,创建一个既有结构又有记录的完整数据表;选择“否”按钮,则不输入记录,生成一个只有结构而无记录的空表,待以后再向表中追加记录(参见3.5.2节)。

2. 记录的输入

在图3.8所示的提示框中单击“是”按钮,便进入数据输入窗口,可以向数据表中输入数据。

表记录格式有两种模式:一种是图3.9所示的浏览模式,另一种是图3.10所示的编辑模式;前者是一条记录占一行,后者是一个字段占一行。用户可以根据需要和喜好,利用“显示”菜单下的“浏览”或“编辑”命令在这两种显示模式之间切换。

图3.9 浏览模式

图3.10 编辑模式

(1)一般数据的输入 在输入窗口中显示了表中记录的全部字段名。对于字符型、数值型、逻辑型、日期型等类型的字段,只要依次输入具体数据即可。

(2)备注型字段数据的输入 在备注型字段中可输入任意长度的文本,方法是:双击名为“memo”的备注型字段标志,进入备注窗口后输入文本内容,如图3.11所示。

图3.11 输入备注型字段内容

输入和编辑好备注型字段内容后,单击备注窗口右上角的“关闭”按钮退出备注窗口,返回记录输入屏幕(原来的备注型字段标志“memo”中的字母“m”变为大写,即“Memo”,表明该备注型字段的内容非空),继续输入其他数据。

(3)通用型字段数据的输入 在通用型字段中可以添加图像、声音及所有可以插入的OLE对象,方法是:双击名为“gen”的通用型字段标志,进入通用型字段的输入编辑窗口。选择“编辑|插入对象”命令,打开图3.12所示的“插入对象”对话框。

若插入的对象是新创建的,则单击“新建”选项,然后从“对象类型”列表框中选择要创建的对象类型,如图3.12(a)所示。单击“确定”按钮后,进入对象创建窗口,在对象创建好之后,退出此窗口即可。

图3.12 “插入对象”对话框

若插入的对象已经存在,则单击“由文件创建”选项,在“文件”文本框中输入文件名,或者单击“浏览”按钮,选择需要的文件,如图3.12(b)所示。然后单击“确定”按钮,对象即插入到编辑窗口中。

编辑好通用型字段的内容后,单击编辑窗口右上角的“关闭”按钮,返回记录输入屏幕(原来的通用型字段标志“gen”中的字母“g”变为大写,即“Gen”,表明该通用型字段的内容非空),继续输入其他数据。

要删除备注型字段或通用型字段的内容,可双击字段名,打开包含其内容的编辑窗口,选择“编辑|清除”命令。

根据表3.4给出的“学生”表内容,输入记录,完成后单击窗口右上角的“关闭”按钮或按Ctrl+W组合键退出。

注意:在表中定义了备注型或通用型字段后,系统会自动生成与表文件名相同且扩展名为.FPT的备注文件,用来存放备注型或通用型字段的实际内容。表备注文件将随着表文件的打开而打开,随着表文件的关闭而关闭。

无论一个表中定义了多少个备注型字段或通用型字段,系统只生成一个.FPT文件,存放这个表中所有备注型字段和通用型字段的内容。

3.3.3 数据库表的建立

数据库表是与数据库相关联的表,它具有自由表没有的一些属性,如长字段名、数据有效性规则的定义等,它与其他大型数据库管理系统更相近,更符合SQL国际标准。因此,在开发数据库应用系统时,更多的是使用数据库表,建立数据库表有以下几种方法。

1. 在数据库中建立新表

(1)在项目管理器或数据库设计器中建立新表

使用项目管理器创建的表自动包含在项目文件中,例如,在“教学”项目的“教学管理”数据库中建立“课程”表,方法是:

① 打开“教学.PJX”项目文件,启动项目管理器。

② 选择“数据”标签,单击“数据库”项前的“+”号,展开该数据项。

③ 单击“教学管理”数据库项前的“+”号展开该数据库。

④ 选定“表”,然后单击“新建”按钮,如图3.13所示。

图3.13 在项目管理器中新建表

也可以在项目管理器中双击“教学管理”数据库,打开数据库设计器,右击窗口空白处,从快捷菜单中选择“新建表”(如图3.14所示),打开“新建表”对话框。

图3.14 在数据库设计器中新建表

⑤ 在“新建表”对话框中,单击“新建表”按钮,出现“创建”对话框。选择保存位置“E:\VFP6\DATA”,输入表文件名“课程.DBF”后即可打开图3.15所示的表设计器。

后面的操作与建立自由表的方法相同,按表3.2和表3.5所示的“课程”表结构和内容,定义字段并输入记录。

图3.15 数据库表的表设计器界面

(2)当数据库处于打开状态时,用建立自由表的方法创建的新表将包含在该数据库中。

【例3.5】 用命令方式在“教学管理”数据库中建立“成绩”表。

        OPEN  DATABASE  E:\VFP6\教学管理
        CREATE  E:\VFP6\DATA\成绩        && “成绩”表的结构和内容如表3-3和表3-6所示

2. 将自由表添加到数据库中

当数据库建好之后,可以向数据库中添加已有的自由表,使其成为数据库表。例如,将前面建立的“学生”表添加到“教学管理”数据库中。

表3.3 “成绩”表结构

(1)项目管理器方式

① 打开“教学”项目,启动项目管理器。

② 选择“数据”选项卡,展开“教学管理”数据库。

③ 选择“表”项,单击“添加”按钮,如图3.16所示。

图3.16 在数据库中添加自由表

④ 在“打开”对话框中选择“E:\VFP6\data”文件夹中的“学生.dbf”表,如图3.17所示。单击“确定”按钮,该数据表即添加到当前数据库中,如图3.18所示。

图3.17 选择要添加的自由表

图3.18 将“学生”表添加到数据库中

也可以打开数据库设计器,选择“数据库|添加表”命令,然后从“打开”对话框中选择要添加到当前数据库的自由表。

(2)命令方式

格式:ADD TABLE <数据表文件名>

功能:向已打开的数据库中添加指定名字的数据表。

【例3.6】 用命令方式向“教学管理”数据库中添加“学生”表。

        OPEN  DATABASE  E:\VFP6\教学管理
        ADD TABLE  E:\VFP6\DATA\学生

数据库中的数据表只能属于这个数据库文件。如要向当前数据库中添加已属于其他数据库的表,则需先把该数据表从其他数据库中移出来,才能将它添加到当前数据库中。

3. 从数据库中移去数据表

(1)项目管理器方式

在项目管理器中,将数据库中的表展开,选中要移去的表;然后单击“移去”按钮,出现图3.19所示的提示对话框,单击“移去”按钮即可。

图3.19 移去数据库表时的提示框

若在上述提示框中单击“删除”按钮,则不仅从数据库中移去该表,同时也从磁盘上删除了该表。做表费时间,因此初学者要谨慎使用该功能。

也可以打开数据库设计器,选择要移去或删除的数据表,然后选择“数据库|移去”命令,在随后出现的提示框中单击“移去”或“删除”按钮。

(2)命令方式

格式:REMOVE TABLE <数据表文件名> [DELETE][RECYCLE]

功能:从当前数据库中移去或删除指定的数据表。

说明:如不带DELETE选项,则将指定数据表从数据库中移去,使之成为自由表;如带DELETE选项,则表示从数据库中移去数据表的同时从磁盘上删除该表;如同时带DELETE和RECYCLE选项,则表示把指定的数据库表从数据库中移去后,放入Windows回收站中,而不是立即从磁盘上删除。

【例3.7】 用命令方式从“教学管理”数据库中移去“成绩”表。

        OPEN  DATABASE  E:\VFP6\教学管理
        REMOVE  TABLE  E:\VFP6\DATA\成绩

3.4 数据表的基本操作

前面创建数据库时介绍过,当一个数据库建立后,这个数据库文件就存储了有关该数据库的所有信息,如数据库表、视图、联接和存储过程等,但它并不在物理上包含任何附属对象,如表或字段。VFP仅在数据库文件中存储指向数据库表文件的路径指针。因此,对数据库表的操作,既可以通过项目管理器或数据库设计器进行,也可以单独进行,单独操作时必须先打开相应的数据表文件。

3.4.1 数据表的浏览

1. 数据表文件的打开

(1)菜单方式

选择“文件|打开”命令,出现图3.20所示的“打开”对话框,选择文件所在的路径和类型(.dbf)并输入文件名,单击“确定”按钮,或者直接双击要打开的文件。

图3.20 “打开”对话框

(2)命令方式

格式:USE [<表文件名>] [EXCLUSIVE]

[SHARED]

功能:打开指定的表文件。

说明:

① <表文件名>中可以省略扩展名.dbf。若命令行中不带<表文件名>,则表示关闭当前打开的数据表文件。

② EXCLUSIVE选项表示以独占方式打开数据表文件,与在“打开”对话框中选择“独占”复选框等效,即不允许其他用户在同一时刻也使用该数据库。SHARED选项表示以共享方式打开数据表文件,与在“打开”对话框中不选择“独占”复选框等效,即允许其他用户在同一时刻也使用该数据库。当要修改数据表结构或物理删除数据表中的记录时,必须使该数据表处于“独占”方式,否则系统不允许进行修改或删除操作。

2. 表结构的浏览与显示

(1)浏览表结构 对已建立的数据表可以打开表设计器查看其结构。

① 项目管理器方式 打开项目管理器,选择“数据”选项卡,将数据库展开至表项。选定要浏览的表,单击“修改”按钮;或双击该表,打开相应的表设计器。

② 菜单方式 选择“文件|打开”命令,打开要浏览的数据表;然后选择“显示|表设计器”命令,打开表设计器。

(2)显示表结构 使用LIST或DISPLAY命令可以在主窗口中显示当前数据表的结构。

格式:LIST|DISPLAY STRUCTURE

说明:LIST命令用于连续显示,DISPLAY命令用于分页显示。执行该命令后,将显示文件名、数据表记录的个数、数据表文件更新的日期、每个字段的定义,以及一个记录的字节总数、备注型字段的块长度等信息。

【例3.8】 用命令方式打开“学生”表文件,并显示表结构,然后将其关闭。

        USE  E:\VFP6\DATA\学生      && 打开“学生”表文件
        LIST  STRUCTURE             && 显示“学生”表结构
        USE                         && 关闭处于打开状态的“学生”表文件

显示结果:

        表结构: E:\VFP6\DATA\学生.dbf
        数据记录数:      10
        最近更新的时间:  05/14/10
        备注文件块大小:  64
        代码页:936
        字段     字段名      类型     宽度     小数位     索引     排序     NULLS
          1      学号       字符型       8                                  否
          2      姓名       字符型       8                                  否
          3      性别       字符型       2                                  否
          4      出生日期   日期型       8                                  否
          5      系别       字符型       10                                 否
          6      贷款否     逻辑型       1                                  否
          7      简历       备注型       4                                  否
          8      照片       通用型       4                                  否
        **总计**         46

结果中的最后一行为总计行。数据总宽度等于各字段宽度之和再加1,多加的1字节用来存放记录的逻辑删除标志(有关记录的逻辑删除将在3.5.4节中介绍)。

3. 记录的浏览与显示

(1)在浏览窗口中浏览记录

① 项目管理器方式 打开项目管理器,选择“数据”选项卡,将数据库展开至表项。选定要浏览的表,单击“浏览”按钮,出现图3.9所示的浏览窗口。

也可以双击“数据库”项,打开数据库设计器,先选定要浏览的表,然后选择“数据库|浏览”命令;或者右击要浏览的表,从快捷菜单中选择“浏览”命令,打开浏览窗口。

对于备注型字段或通用型字段内容,只要在浏览窗口中双击相应的字段标志(“Memo”或“Gen”),打开编辑窗口即可进行浏览。

② 菜单方式 选择“文件|打开”命令,打开要浏览的数据表。然后从“显示”菜单中选择“浏览”或“编辑”命令,打开浏览窗口。

③ 命令方式

格式:BROWSE

功能:打开浏览窗口,显示当前数据表中的记录。

说明:使用BROWSE命令之前,数据表必须处于打开状态。

【例3.9】 用命令方式打开“学生”表,并在浏览窗口中浏览表记录,然后将其关闭。

        USE  E:\VFP6\DATA\学生      && 打开“学生”表文件
        BROWSE                      && 浏览“学生”表记录
        USE                         && 关闭处于打开状态的“学生”表文件

在浏览窗口中,字段的相对位置是根据用户建立表结构时的顺序排列的,但也可以根据需要来改变这种排列方式,方法是:将鼠标移到要移动字段的列标头处(鼠标指针变为向下箭头),按住鼠标左键(该字段名变为黑色),然后拖动鼠标到列标头的新位置处,松开鼠标,该字段的位置即随之改变。如图3.21所示,将“学生”表中的“出生日期”字段移到了第一列,将“性别”字段移到了第二列。

图3.21 改变字段显示位置

注意:这种方式只能临时改变字段在浏览窗口的当前显示位置,而不会改变表结构中的字段位置。若要永久改变字段在表结构中的位置,可以用3.5.1节中介绍的修改表结构的方法。

(2)在浏览窗口中有选择地浏览记录

对于一个数据量很大的表,用户可能不想在浏览窗口中显示表中的所有记录或所有字段信息,而只想有选择地显示某些记录或某些字段的信息,在VFP中可以通过对记录或字段的筛选来实现。

① 菜单方式 打开浏览窗口,选择“表|属性”命令,打开“工作区属性”对话框。在“数据过滤器”文本框中输入筛选条件,单击“确定”按钮,浏览窗口中就只显示满足筛选条件的记录。

按图3.22所示设置筛选条件,浏览窗口中只显示所有女生的记录(如图3.23所示)。删除“数据过滤器”文本框中的筛选表达式,可恢复显示所有记录。

图3.23 筛选记录

图3.22 “工作区属性”对话框

在“工作区属性”对话框的“允许访问”栏中选中“字段筛选指定的字段”单选项(如图3.24(a)所示),单击“字段筛选”按钮,打开“字段选择器”对话框。在“所有字段”列表框中选中要显示的字段,并单击“添加”按钮,或者直接双击要显示的字段,将其移入“选定字段”列表框,如图3.24(b)所示。设置完毕后,返回“工作区属性”对话框,单击“确定”按钮,浏览窗口中便只显示选定的字段内容。

图3.24 设置字段的筛选

按图3.24所示进行设置,浏览窗口中只显示所筛选的字段内容(如图3.25所示)。

图3.25 字段筛选

若要恢复显示所有字段,只要在“工作区属性”对话框中的“允许访问”栏内选择“工作区中的所有字段”单选项,即可取消对字段访问的限制。

② 命令方式

格式1:SET FILTER TO [<条件表达式>]

功能:设置数据过滤器,使得数据表中只有满足指定条件的记录才可以被访问。

说明:<条件表达式>代表筛选条件,满足该条件的记录可以访问,不满足该条件的记录不允许访问;若没有指定<条件表达式>,则表示取消当前表的筛选条件,使表中所有记录都可以访问。

【例3.10】 用命令方式浏览“学生”表中所有女生的记录。

        USE E:\VFP6\DATA\学生
        SET FILTER TO性别="女"
        BROWSE
        USE

【例3.11】 取消例3.10中的记录筛选,浏览“学生”表中所有学生的记录。

        USE  E:\VFP6\DATA\学生
        SET  FILTER  TO                      && 取消当前表的记录筛选条件
        BROWSE
        USE

格式2:SET FIELDS TO ALL|<字段名表>

功能:设置字段过滤器,使得数据表中只有指定的字段才可以被访问。

说明:若指定<字段名表>,则出现在字段名表中的字段可以访问,数据表中的其他字段不允许访问;若使用ALL选项,则取消对字段的限制,表中所有字段都可以访问。

【例3.12】 用命令方式浏览“学生”表中的学号、姓名、系别和贷款否4个字段。

        USE  E:\VFP6\DATA\学生
        SET  FIELDS  TO  学号,姓名,系别,贷款否   && 只能访问当前表记录的4个字段
        BROWSE
        USE

【例3.13】 取消例3.12中对字段访问的限制,浏览“学生”表中所有字段内容。

        USE E:\VFP6\DATA\学生
        SET  FIELDS  TO  ALL                 && 可以访问当前表记录的所有字段
        BROWSE
        USE

(3)显示记录

使用LIST或DISPLAY命令可以在VFP主窗口中显示记录内容。

格式:LIST|DISPLAY [<范围>][[FIELDS] <表达式表>][WHILE <条件>][FOR<条件>]

功能:连续或分页显示当前数据表文件的全部或部分记录内容。

说明:命令中各选项的含义可参照2.5节中的说明。当命令中不带<范围>和<条件>选项时,LIST命令默认显示全部记录,而DISPLAY命令仅显示当前记录。

【例3.14】 显示“学生”表中所有女生的学号、姓名和所在系信息。

        USE  E:\VFP6\DATA\学生.DBF
        LIST  FIELDS学号,姓名,系别  FOR  性别="女"
        USE

显示结果:

3.4.2 记录的定位

1. 记录指针

向表中输入记录时,系统会按照输入次序为每个记录加上相应的记录号。VFP为每一个打开的数据表都设置了一个用来指示记录位置的指针,称为记录指针。记录指针存放的是记录号,用来标识数据表的当前记录。图3.26示意了表文件的逻辑结构,最上面的记录是首记录(标识为TOP),最下面的记录是尾记录(标识为BOTTOM)。首记录之前有一个文件起始标识,称为Begin of File(BOF);尾记录或末记录之后有一个文件结束标识,称为End of File(EOF)。

图3.26 表文件逻辑结构

表文件刚打开时,记录指针总是指向首记录的。通过移动记录指针,定位记录,就可以对指定的当前记录进行操作了。

2. 记录指针的移动

记录指针的移动包括绝对移动、相对移动和条件定位三种方式,可以通过菜单或命令操作来实现。

(1)菜单方式

当打开的数据表处于浏览、编辑等状态时,在VFP的主菜单中会出现一个“表”菜单项,提供了记录定位的各种操作。

① 在项目管理器中,选择“学生”表,单击“浏览”按钮,打开浏览窗口。

② 选择“表|转到记录”命令,展开其下级子菜单,如图3.27所示。可以根据需要选择其中的一项。

图3.27 “表”菜单中的记录定位命令

● 第一个 指向数据表的首记录(第一条记录)。

● 最后一个 指向数据表的尾记录(末记录)。

● 下一个 指向当前记录的下一条记录。

● 上一个 指向当前记录的上一条记录。

● 也可以直接在浏览窗口中单击某条记录,使其成为当前记录,在当前记录所在行的最左列有一个向右的黑三角标记,见图3.21。

● 记录号 指向给定记录号的某条记录。执行该命令后,系统将弹出一个图3.28所示的对话框,要求输入记录号的数值。单击“确定”按钮后,指针即指向用户指定的记录位置。

图3.28 输入记录号对话框

● 定位 指向满足条件的第一条记录。执行该命令后,出现图3.29所示的对话框,供用户设置定位记录的条件和范围。

图3.29 “定位记录”对话框

可以直接在“For”条件或者“While”条件文本框中输入一个条件表达式,也可以单击文本框右边的“…”按钮,打开图3.30所示的表达式生成器,生成一条表达式。

图3.30 表达式生成器

假设表达式为“性别="男"”,可以按如下方法操作:首先在“字段”列表框中双击“性别”字段,该字段名即出现在表达式生成器上方的表达式文本编辑框中;然后从“逻辑”函数列表框中选择“=”运算符,或直接输入“=”;在“=”后输入字符串常量“"男"”。单击“确定”按钮后,该表达式即出现在图3.29所示的条件文本框中。

最后,单击“定位”按钮,记录指针即指向满足条件的第一条记录。

(2)命令方式

在程序设计中,定位记录主要使用命令方式,它比菜单方式更方便、灵活。

① 指针的绝对移动命令

格式:GO|GOTO [RECORD]<记录号>|TOP|BOTTOM

功能:将当前数据表的记录指针移到指定记录号的记录上。GO TOP表示将指针移到首记录,GO BOTTOM表示将指针移到末记录。

说明:GO命令与GOTO命令功能相同。

【例3.15】 用命令方式定位并显示“学生”表的第1条、第6条和最后一条记录。

        USE E:\VFP6\DATA\学生
        GO  TOP                         && 强调移动记录指针到首记录处
        DISPLAY
        GO  6                           && 移动记录指针到第6条记录处
        DISPLAY
        GO  BOTTOM                     && 移动记录指针到末记录处
        DISPLAY

显示结果:

② 指针的相对移动命令

格式:SKIP [+|-][<算术表达式>]

功能:将当前数据表的记录指针从当前记录位置向前或向后移动若干条记录位置。

说明:<算术表达式>可以是常量,也可以是已赋过值的变量,但该值必须为整数,表示相对于当前记录位置要移动的记录个数。<算术表达式>前带“+”,表示使记录指针从当前位置向下移动(“+”可以省略);<算术表达式>前带“-”(“-”不可省略),表示使记录指针从当前位置向上移动。SKIP命令与SKIP 1命令等价。

【例3.16】 打开“学生”表,使用SKIP命令移动记录指针。

        USE E:\VFP6\DATA\学生
        GO  2                           && 绝对移动记录指针到第2条记录处
        DISPLAY
        SKIP  5                          && 相对移动记录指针5条记录(至第7条记录处)
        DISPLAY
        SKIP  -3                         && 相对移动记录指针-3条记录(至第4条记录处)
        DISPLAY

显示结果:

③ 条件定位命令

格式:LOCATE [<范围>] FOR <条件> [WHILE <条件>]

功能:在当前数据表的指定范围内查找满足条件的第一条记录。

说明:

● 如找到满足条件的记录,则指针指向该记录;如没有找到,则指针指向表文件结束位置。可以用FOUND( )函数测试是否找到满足条件的记录。

● FOR <条件> 表示在指定范围内,定位满足条件的第一条记录。

● WHILE <条件> 表示仅当条件满足时才进行记录的定位。如指定范围内的第一条记录就不满足条件,则立即结束操作,不论后面是否还有符合条件的记录存在。

● 如要使指针指向下一条满足条件的记录,必须使用继续定位命令CONTINUE。

【例3.17】 打开“学生”表,用LOCATE命令定位所有女生的记录。

        USE  E:\VFP6\DATA\学生
        LOCATE  FOR性别="女"
        ?FOUND()                        && 显示结果  .T.
        DISPLAY                         && 显示当前记录

显示结果:

继续执行命令:

        CONTINUE                   && 用LOCATE命令继续查找必须用CONTINUE配合
        DISPLAY

显示结果:

可继续使用CONTINUE命令定位其他性别为“女”的记录,直到?FOUND( )为.F.。

3.5 数据表的维护

数据表的维护主要包括两方面,一是表结构的修改,二是对记录的添加、编辑和删除操作。

3.5.1 表结构的修改

数据表结构的修改包括增加或删除字段,修改字段名、类型、宽度,增加、删除或修改索引。对于数据库表,还可以修改或删除有效性规则等(索引和有效性规则见3.6.2节和3.7.2节),修改表结构可以在表设计器中进行,而且最好在输入记录数据之前进行。

1. 项目管理器方式

打开项目管理器,将数据库中的表展开,选择要修改结构的表,单击“修改”按钮,或双击要修改的表后,进入表设计器窗口。

(1)修改已有的字段 直接修改字段的名称、类型和宽度即可。

(2)增加新字段

① 在原有字段后增加新字段 将光标移到最后,定义新的字段名、类型和宽度。

② 在两个字段之间插入新字段 选中要插入新字段的行(将鼠标指向字段行最左边按钮,鼠标指针变为双箭头,单击按钮即可选中该字段行),再单击“插入”按钮,便会插入一个新字段,原来字段下移一行。可在新字段位置上输入新的字段名,定义类型和宽度。

(3)删除字段 选定要删除的字段,然后单击“删除”按钮。

(4)改变字段顺序 将鼠标移到字段行最左边的按钮上,按住鼠标,然后上、下拖动到合适位置处再松开鼠标。

表结构修改完毕后,单击“确定”按钮,退出表设计器。

2. 命令方式

格式:MODIFY STRUCTURE

功能:打开表设计器,显示并修改当前数据表的结构。

改变表的结构时,系统会自动备份当前的表文件。备份文件的扩展名是.BAK,备注文件的备份文件扩展名是.TBK。如在修改表结构时出现错误,可把修改后的表文件删除,再把.BAK文件和.TBK文件分别改为原文件扩展名.DBF和.FPT,即恢复原来的数据表文件。

【例3.18】 用命令方式打开并修改“学生”表的结构。

        USE E:\VFP6\DATA\学生
        MODIFY  STRUCTURE
        USE

3.5.2 记录的添加

记录的添加一般是从数据表的末记录之后追加,也可从任一条记录之前或之后插入,还可从其他表文件中追加进来。

1. 在浏览窗口中追加记录

在建立数据表的结构时,如没有选择“立即输入数据”而只建一个无记录的空表,或者要在已有记录的数据表中再增加一些记录,可以用追加的方式向表中输入数据。

(1)菜单方式

通过项目管理器或BROWSE命令打开浏览或编辑窗口,选择“显示|追加方式”命令,则在原有末记录后出现一个空记录,如图3.31所示,供用户输入具体内容。一次可以追加多条新记录,直到关闭浏览窗口。

图3.31 追加记录

说明:打开浏览或编辑窗口后,如选择“表|追加新记录”命令,则一次只能向表中追加一条新记录。

(2)命令方式

格式:APPEND[BLANK]

功能:在当前数据表的尾部(末记录之后)添加记录。

说明:APPEND BLANK命令只是在当前数据表的末尾添加一条空白记录,并不打开浏览或编辑窗口。可以用下面将要介绍的BROWSE等编辑命令交互修改空白记录,或用REPLACE命令直接修改该空白记录。

在命令窗口中输入APPEND命令并按回车键后,将会出现一个编辑窗口,如图3.32所示,此时,一次可以连续输入多条新记录,直到关闭该窗口。

图3.32 APPEND命令窗口

2. 记录的插入

要在数据表的原有记录中间插入新记录,可以使用INSERT命令完成。

格式:INSERT [BEFORE] [BLANK]

功能:在当前数据表的任一条记录之前或之后插入一条记录。

说明:如带BEFORE选项,则在当前记录之前插入一条新记录。如不带BEFORE选项,则默认在当前记录之后插入一条新记录。带BLANK选项,表示插入一条空记录。

执行INSERT命令,也会出现图3.32所示的界面。

例如,要在第3条记录和第4条记录之间插入一条新记录,可以使用下面的命令:

        GO 3
        INSERT             && 或者使用以下方式
        GO 4
        INSERT  BEFORE

3. 从其他文件中追加记录

如当前数据表中要添加的记录已经在其他文件中存在,可以将这些记录从其他文件中追加到当前数据表记录的末尾。

假设有一个“课程安排”表,包含课程号(C, 3)、课程名(C, 20)、教师(C, 8)、教室(C, 10)、上课时间(C, 30)字段,其结构已经建好,但记录为空,需要从已包含数据的“课程”表中提取相对应的记录,可以用以下方法完成。

(1)菜单方式

① 选择“文件|打开”命令,打开“课程安排”表;再从“显示”菜单中选择“浏览”或“编辑”命令,打开浏览或编辑窗口。

② 选择“表|追加记录”命令,出现图3.33所示的“追加来源”对话框。在“类型”列表框中选择源文件的类型,在“来源于”文本框中输入来源文件名(或单击浏览按钮,选择来源的文件),此处为“e:\vfp6\data\课程.dbf”。

图3.33 “追加来源”对话框

③ 单击对话框中的“选项”按钮,打开图3.34所示的“追加来源选项”对话框,单击“字段”按钮,出现“字段选择器”。在“所有字段”列表框中选定所需的字段,单击“添加”按钮,将其添加至“选定字段”列表框,如图3.35所示。

图3.34 “追加来源选项”对话框

图3.35 字段选择器

如对来源的表文件中的记录有条件限制,可以单击“For”按钮,在出现的表达式生成器窗口中输入一个条件表达式。

④ 完成所有设置后,返回图3.33所示的对话框,单击“确定”按钮,即可将“课程”表中的“课程号”和“课程名”字段的内容追加到“课程安排”表中,结果如图3.36所示。

图3.36 从“课程”表中追加的记录

(2)命令方式

格式:APPEND FROM <源表文件名> [FIELDS <字段名表>] [FOR <条件>]

功能:将满足条件的记录按指定的字段从源表文件追加到当前数据表的末尾。

说明:只有名称和类型相匹配的字段内容才予以追加。如源表文件字段的宽度大于当前表相应字段的宽度,字符型字段将被截尾,数值型字段填写“*”号以示溢出。

【例3.19】 用命令方式将“课程”表中的相应数据追加到“课程安排”表中。

        USE  E:\VFP6\DATA\课程安排
        APPEND  FROM  E:\VFP6\DATA\课程.DBF  FIELDS  课程号,课程名
        BROWSE
        USE

3.5.3 记录的编辑

1. 在浏览窗口中编辑记录

(1)项目管理器方式

打开项目管理器,将数据库展开至表项,选择要编辑记录的表,单击“浏览”按钮,打开浏览窗口,再用定位记录的方法找到要修改的记录,将光标定位在要修改的字段值上,直接修改即可。全部修改完毕后,关闭浏览窗口,所做的修改将自动保存在表文件中。

若要修改备注型字段或通用型字段内容,可以在浏览窗口中双击相应的字段标志(“Memo”或“Gen”),打开编辑窗口进行相应的编辑或修改。

(2)命令方式

格式:BROWSE [FIELDS <字段名表>] [FREEZE <字段名>]

[NOAPPEND] [NOMODIFY] [FOR <条件表达式>]

功能:打开浏览窗口,显示表文件的记录,并进行全屏幕编辑和修改。

说明:

① FIELDS <字段名表> 指定在浏览窗口中出现的字段,并以在字段名表中指定的顺序显示。无此选项,表示可编辑所有字段。

② FREEZE <字段名> 使光标冻结在某字段上,以便仅能修改该字段,其他字段则只能浏览不能修改。

③ NOAPPEND禁止向数据表中追加记录。

④ NOMODIFY禁止修改或删除数据表中的记录。

⑤ FOR <条件表达式>指定一个条件,使得浏览窗口中只显示满足条件的记录。

【例3.20】 用命令方式打开“学生”表,显示并修改姓名、系别和贷款否3个字段。

        USE  E:\VFP6\DATA\学生
        BROWSE  FIELDS  姓名,系别,贷款否
        USE

结果如图3.37所示。

图3.37 BROWSE命令编辑记录

2. 批量修改记录

上述方法只能在浏览窗口中对记录逐条进行编辑修改,如要同时对一批记录中的某个字段或某几个字段进行编辑修改,可以使用成批修改记录的操作。

(1)菜单方式

打开数据表,使其显示在浏览或编辑窗口中,然后选择“表|替换字段”命令,出现图3.38所示的“替换字段”对话框。在“字段”下拉列表框中选择当前数据表中要替换的字段,在“替换为”文本框中输入要替换指定字段内容的表达式(也可以单击文本框右侧的“…”按钮,利用表达式生成器建立表达式),在“替换条件”栏中根据需要指定记录范围和条件。

图3.38 “替换字段”对话框

假设已在“学生”表中增加了一个“助学金”字段(类型为N,宽度为6,小数位数为2),若要给管理系的每个学生增加50.0元助学金,可在“替换字段”对话框中按图3.38所示进行相应的设置。单击“替换”按钮后,“学生”表中所有管理系学生的助学金都增加了50.0元,结果如图3.39所示。

图3.39 替换“助学金”字段结果

(2)命令方式

格式:REPLACE [<范围>] [<字段1> WITH <表达式1> [ADDITIVE][,<字段2>WITH <表达式2>] [ADDITIVE]…] [FOR <条件>] [WHILE <条件>]

功能:对当前数据表中指定范围内满足条件的记录进行批量修改。

说明:

① 该命令可以同时修改多个字段的内容,即用<表达式1>的值替换<字段1>中的数据、用<表达式2>的值替换<字段2>中的数据,…,依次类推。

② 如表达式值的长度比数值型字段定义的宽度大,此命令首先截去多余的小数位,剩下小数部分四舍五入;如还达不到要求,则以科学计数法保存此字段的内容;如还不满足,此命令将用星号(*)代替该字段内容。

③ ADDITIVE选项只适用于备注型字段的修改。若有此选项,表示将表达式的内容添加在原来备注内容的后面;否则,表达式的内容将会覆盖原来的备注内容。

④ 若无FOR选项,则对<范围>指定的记录进行替换;若无<范围>选项,则对整个数据表中符合条件的记录进行替换。若两个选项均默认,则仅对当前记录进行替换。

【例3.21】 打开“学生”表,给管理系的每个学生减去15.5元助学金,用REPLACE命令完成,并显示结果。

        USE  E:\VFP6\DATA\学生
        REPLACE  助学金  WITH  助学金-15.50  FOR  系别="管理"
        LIST学号,姓名,系别,助学金
        USE

显示结果:

3.5.4 记录的删除

数据表中不需要的数据可以随时删除。在VFP中,删除记录有逻辑删除和物理删除两种。逻辑删除只是给记录加上删除标记,并没有从数据表中将其清除,需要时还可以恢复;物理删除则是真正地从表文件中清除记录,不可再恢复。

1. 记录的逻辑删除

记录的逻辑删除有以下三种方法。

(1)鼠标操作

打开项目管理器,将数据库展开至表项,选中要操作的表,单击“浏览”按钮,打开浏览窗口。单击要逻辑删除的记录的第一个字段前面的空白处,使其颜色变黑,表示此记录已被逻辑删除了,如图3.40所示。

图3.40 逻辑删除记录

使用这种方法可以给多条记录加逻辑删除标记。

(2)菜单方式

打开浏览窗口,选择“表|删除记录”命令,出现“删除”对话框。根据需要分别设置“作用范围”、“FOR”条件或者“WHILE”条件,然后单击“删除”按钮,即进行了逻辑删除。

按图3.41所示进行设置,结果将逻辑删除“学生”表中所有男生的记录。

图3.41 “删除”对话框

(3)命令方式

格式:DELETE [<范围>] [FOR <条件>] [WHILE <条件>]

功能:给当前数据表文件中满足条件的记录加删除标记。

说明:如省略<范围>和<条件>选项,则只给当前记录加删除标记。

【例3.22】 打开“学生”表,将最后一条记录逻辑删除。

        USE  E:\VFP6\DATA\学生
        GO  BOTTOM              && 将记录指针移至末记录
        DELETE
        DISPLAY
        USE

显示结果:

2. 逻辑删除记录的恢复

使用以下方法可以取消记录的逻辑删除标记。

(1)鼠标操作

在浏览窗口中,单击逻辑删除标记,取消黑色方框,即恢复了已删除的记录。

(2)菜单方式

打开浏览窗口,选择“表|恢复记录”命令,出现“恢复记录”对话框。根据需要分别设置“作用范围”、“For”条件或者“While”条件,然后单击“恢复记录”按钮,即可将满足条件的记录恢复。按图3.42所示进行设置,将恢复“学生”表中所有被逻辑删除的男生记录。

图3.42 “恢复记录”对话框

(3)命令方式

格式:RECALL [<范围>] [FOR <条件>] [WHILE <条件>]

功能:取消记录的逻辑删除标记,恢复被逻辑删除的记录。

说明:如省略<范围>和<条件>选项,则只将当前记录的逻辑删除标记取消。

【例3.23】 打开“学生”表,先逻辑删除1993年以前出生的学生记录,再将其恢复。

        CLEAR                         &&CLEAR命令用来清除主窗口中的显示内容
        USE  E:\VFP6\DATA\学生
        DELETE  FOR  YEAR(出生日期)<1993
        LIST  姓名,性别,出生日期,系别
        RECALL  ALL
        LIST  姓名,性别,出生日期,系别
        USE

显示结果:

3. 记录的物理删除

(1)将带逻辑删除标记的记录物理删除

① 菜单方式

图3.43 确认对话框

打开浏览窗口,选择“表|彻底删除”命令,在图3.43所示的对话框中单击“是”按钮,所有带逻辑删除标记的记录就从当前表文件中彻底清除了。

② 命令方式

格式:PACK

功能:把当前数据表中带逻辑删除标记的记录从磁盘中彻底删除。

【例3.24】 打开“学生”表,先逻辑删除最后一条记录,再将其物理删除。

        USE  E:\VFP6\DATA\学生
        GO  BOTTOM
        DELETE
        DISPLAY
        PACK
        LIST姓名,性别,系别
        USE

显示结果:

注意:被物理删除的记录是不能够再恢复的,所以对该命令要慎用。

(2)记录的一次性删除

使用ZAP命令可以一次性将当前数据表中的所有记录从表文件中删除,仅保留表结构。

格式:ZAP

功能:将数据表中的所有记录一次性彻底删除,只保留数据表结构。

说明:

① 执行ZAP命令与先执行DELETE ALL,再执行PACK命令效果相同。要将当前数据表中的所有记录从表文件中删除,直接执行ZAP命令要快得多。

② 执行ZAP命令后,当前数据表中的所有记录都被物理删除,且不可恢复,所以使用ZAP命令一定要十分谨慎。

【例3.25】 用ZAP命令删除“课程安排”表中的所有记录。

        CLEAR
        USE  E:\VFP6\DATA\课程安排
        ?RECCOUNT()              &&  RECCOUNT() 函数用来统计当前数据表中的记录个数
        ZAP
        ?RECCOUNT( )
        USE

显示结果:

        6
        0

3.5.5 数据表的复制

为了防止数据丢失或损坏,应该定期对数据表进行备份,以防不测。另外,有的时候需要根据已建立的数据表间接建立其他数据表文件,这时可进行数据表的复制操作。

1. 数据表文件的复制

(1)菜单方式

① 选择“文件|打开”命令或USE命令,打开要复制的表文件。

② 选择“文件|导出”命令,打开图3.44所示的“导出”对话框,选择复制的文件类型(此处为DBF表文件),输入复制后的目标文件名(可在“E:\VFP6”下建立一个名为“DATA-COPY”的子文件夹,用来保存备份的表文件)。如执行该操作时没有打开数据表,可以在“来源于”文本框中输入被复制的源文件(或者单击文本框右边的“浏览”按钮,选择一个源文件)。

图3.44 “导出”对话框

如要复制的不是整个数据表,而是数据表中的部分内容,可以单击“选项”按钮,打开图3.45所示的“导出选项”对话框,选择要复制的记录及要复制的字段。

图3.45 “导出选项”对话框

③ 单击“确定”按钮,则当前表文件或表文件中指定的记录或指定的字段内容就被复制到目标位置。

用“导出”方式对数据表进行复制时,VFP系统会自动将表的备注文件(.FPT)一起复制,也就是表文件(.DBF)和表备注文件(.FPT)是同时被复制的。在Windows的资源管理器中进行复制操作时,如只复制表文件,而没有复制表的备注文件,则复制以后的表文件是打不开的,此时VFP系统会显示一个消息框,告知用户“缺少备注文件”。

(2)命令方式

格式:COPY TO <新表文件名> [<范围>] [FIELDS <字段名表>]

[FOR <条件>] [WHILE <条件>]

功能:将当前数据表文件的内容全部或部分复制到新文件中。

说明:无任何选项时,将复制一个与当前数据表文件的结构和内容完全相同的新表文件。如指定<范围>、<字段名表>或<条件>,则将指定的记录或字段复制到新表文件中。

【例3.26】 将“学生”表中法律系的学生记录复制到“法律学生”表中。

        USE  E:\VFP6\DATA\学生.DBF
        COPY  TO  E:\VFP6\DATA-COPY\法律学生.DBF  FOR  系别="法律"
        USE  E:\VFP6\DATA-COPY\法律学生
        LIST
        USE

显示结果:

2. 数据表结构的复制

用COPY STRUCTURE命令可将一个数据表的结构复制到新表中。

格式:COPY STRUCTURE TO <新表文件名> [FIELDS <字段名表>]

功能:将当前表文件的结构全部或部分复制到新的数据表文件中。

说明:如选择带FIELDS<字段名表>选项,则仅将指定的字段复制到新表文件中;否则,将源数据表的整个结构复制到新表文件中。复制产生的新表文件是一个只有结构而没有记录的空表文件。

【例3.27】 利用“学生”表的表结构,建立一个新的“贷款情况”表,其中包括“姓名”、“系别”和“贷款否”3个字段。

        USE  E:\VFP6\DATA\学生.DBF
        COPY  STRUCTURE  TO  E:\VFP6\DATA-COPY\贷款情况.DBF  FIELDS姓名,系别,贷款否
        USE  E:\VFP6\DATA-COPY\贷款情况.DBF
        LIST  STRUCTURE
        USE

显示结果:

        表结构:                    E:\VFP6\DATA-COPY\贷款情况.DBF
        数据记录数:                0
        最近更新的时间:            05/18/10
        代码页:                    936

3. 数据表文件的更名

(1)项目管理器方式

若表文件属于一个项目,可以在项目管理器中对其重命名。方法是:选中要重命名的表,选择“项目|重命名文件”命令;或者右击要重命名的表,从快捷菜单中选择“重命名”(如图3.46所示),出现图3.47所示的“重命名文件”对话框,输入新的文件名即可。

图3.46 对数据库表重命名

图3.47 “重命名文件”对话框

在创建数据表的过程中,当定义了备注型字段或通用型字段时,VFP系统会自动建立一个扩展名为.FPT的备注文件;当为数据表创建了结构复合索引时(索引的建立将在3.6.2节中介绍),又会生成一个扩展名为.CDX的索引文件,它们都属于数据表的辅助文件,其主文件名与数据表的主文件名相同。在项目管理器中为表文件更名时,VFP系统会自动为表文件的这些辅助文件同时更名,从而保证了数据表的完整性和一致性;否则,更名后的数据表就不能正常使用。

若要在Windows的资源管理器中对表文件执行重命名操作,必须一一更改表文件及其辅助文件的主文件名,麻烦又容易出错。所以,要为项目中的数据表重命名,最好在项目管理器中进行。

(2)命令方式

格式:RENAME <源表文件名> TO <新的表文件名>

功能:将源表文件名改成新的表文件名。

说明:

① 源表文件名和新表文件名中必须带扩展名。如源数据表文件带备注文件,那么单独对源表文件改名后,必须再对.FPT文件改名,否则更名后的表文件无法打开。

② 可以使用通配符对一组文件进行更名。

3.5.6 数据表与数组之间的数据交换

在数据表记录与数组之间进行数据交换是应用程序设计中经常使用的一种操作,它具有传送数据多、传递速度快、使用方便等特点。

1. 将表的当前记录复制到数组

格式:SCATTER [FIELDS <字段名表>] [MEMO] TO <数组名>|MEMVAR

功能:将当前数据表中的当前记录按字段顺序复制到指定的数组或内存变量中。

说明:

① FIELDS <字段名表>指定要传送的字段内容。若省略该选项,则将当前记录的所有字段值传送给数组元素或内存变量。

② 带MEMO选项,表示可以将备注型字段的内容复制到数组中(对应数组元素的类型为字符型,宽度与备注型字段的实际内容相同);否则,备注型字段不被复制。

③ TO <数组名> 指出数据传递到的数组,当前记录的字段内容将按顺序分别复制到该数组的各个元素中,且从数组的第一个元素开始存放。若指定的<数组名>不存在(即没有用DIMENSION语句定义)或已定义的数组元素的个数少于字段个数,则系统将自动建立或重新定义该数组;若已定义的数组元素的个数多于字段个数,则多余的数组元素内容将不被复制。

④ 使用MEMVAR选项表示将字段内容传递到一组内存变量中,且一个字段对应产生一个内存变量,内存变量的名字、类型、宽度与相应的字段变量相同。带MEMO选项时,接收备注型字段的内存变量类型为字符型,宽度与备注型字段的实际内容相同。

【例3.28】 SCATTER命令应用举例。

        CLEAR  MEMORY
        USE  E:\VFP6\DATA\学生

① 将“学生”表的第1条记录复制到数组AA中,包括备注型字段的内容

        GO 1               && 此命令可省略,但为确保记录指针指向首记录,故用之
        SCATTER  TO  AA  MEMO

② 将表中第2条记录的姓名、性别和系别3个字段复制到数组BB中

        SKIP               && 在记录指针指向首记录的基础上,相对移动指针至第2条记录
        SCATTER  FIELDS  姓名,性别,系别  TO  BB

③ 将最后一条记录复制给内存变量

        GO  BOTTOM       && 绝对移动记录指针至末记录
        SCATTER  MEMVAR
        DISPLAY  MEMORY
        USE

显示结果:

2. 将数组复制到表的当前记录

格式:GATHER FROM <数组名>|MEMVAR [FIELDS <字段名表>] [MEMO]

功能:从数组的第1个元素开始,将各元素的值顺序复制到当前记录的指定字段中。

说明:

① MEMVAR表示将同名的内存变量值复制到当前记录的指定字段中,若没有内存变量与指定字段同名,则该字段内容将不被复制。

② 带FIELDS <字段名表>选项表示只将数组或内存变量的值复制到指定的字段中;否则,复制到当前记录的所有字段中。

③ 带MEMO选项表示可以将数组或内存变量的值复制到备注型字段,否则将不被复制。

④ 数组必须已经定义过,并且各数组元素的类型与相应的字段类型相同。

⑤ 如字段个数多于数组元素的个数,则后面多余的字段将不被复制;如数组元素的个数多于字段个数,则多余的数组元素将被忽略。

【例3.29】 GATHER命令应用举例。

        USE  E:\VFP6\DATA\学生
        APPEND  BLANK          && 在“学生”表记录的末记录后增加一条空记录
        *  将数组BB(见例3.28)中的数据复制到当前的空记录中
        GATHER  FROM  BB  FIELDS姓名,性别,系别
        DISPLAY
        APPEND  BLANK
        GATHER  MEMVAR        && 将例3.28中内存变量的值传递给当前记录
        DISPLAY
        USE

显示结果:

3.6 数据表的排序与索引

原始数据表文件中的记录在表中是按照输入时的顺序排列的,称为物理顺序,VFP用记录号予以标识。通常用户在输入记录时,都是随机而不会按照某种特定的顺序输入,所以当用户需要表中的记录能按照某种顺序来显示或处理时,如按照出生日期由小到大排列(即年龄由大到小),按照成绩由高到低排列等,可以使用VFP中的排序或索引功能来重新组织数据表的记录顺序,使其与期望的顺序一致。

3.6.1 数据表的排序

数据表的排序就是把数据表中的记录按照某个字段值的大小顺序重新排列,作为排序依据的字段称为“关键字”。排序操作的结果是生成一个新的数据表文件,其结构和数据可以与源文件完全相同(也可以取自源文件的一部分字段)。排序可以按照关键字值从小到大的顺序进行,也可以按照关键字值由大到小的顺序进行;前者称为升序,后者称为降序。

在VFP中,数据大小的比较:数值型数据按其数值的大小比较,字符型数据按其机内码顺序比较,西文字符按ASCII码的值,汉字按汉字国标码的值;常用的一级汉字是按照拼音顺序排列的,也就是字典顺序;日期型数据按年、月、日的顺序比较。

在VFP中,排序是用SORT命令实现的。

格式:SORT TO <文件名> ON <字段名1> [/A][/D][/C]

[,<字段名2> [/A] [/D] [/C]…] [ASCENDING/DESCENDING]

[<范围>][FOR <条件>] [WHILE<条件>] [FIELDS <字段名表>]

功能:将当前数据表中指定范围内满足条件的记录,按指定字段的升序或降序重新排列,并将排序后的记录按FIELDS子句指定的字段写入新的表文件中。

说明:

① ON子句中字段名1、字段名2等为排序关键字,不包括逻辑型字段、备注型字段和通用型字段。其中,字段名1为主要关键字,字段名2为次要关键字,依此类推;排序时先比较主关键字的值,当主关键字值相同时,再比较次关键字的值,依此类推。

② FIELDS子句指定排序以后的新表所包含的字段个数;若无此选项,则新表中包含原表中的所有字段。

③ 选项 /A表示按字段值的升序排列,可以省略不写;/D表示按字段值的降序排列;/C表示按指定的字符型字段排序时,不区分字母的大小写。/C可以与/D或/A合用,如/AC或/DC。

④ 如对所有关键字段均按升序排序,可使用ASCENDING选项;按降序方式可使用DESCENDING选项。但/A, /D, /C比ASCENDING或DESCENDING优先权高。

⑤ 排序后产生一个新文件,原来的表文件仍存在,且原记录顺序和数据内容未变。

【例3.30】 对“学生”表中所有贷款的学生按“系别”升序排序,并将排序后的新表文件以“贷款学生”为名,存放在“E:\VFP6\DATA-COPY”文件夹中。

        USE  E:\VFP6\DATA\学生
        SORT  TO  E:\VFP6\DATA-COPY\贷款学生   ON  系别  FOR  贷款否
        USE  E:\VFP6\DATA-COPY\贷款学生        && 打开排序后产生的新文件“贷款学生.DBF”
        LIST
        USE

显示结果:

【例3.31】 将“学生”表按“系别”升序排序,系别相同者,按“学号”降序排序。排序后的新文件以“各系学生”为名,存放在“E:\VFP6\DATA-COPY”文件夹中。

        USE  E:\VFP6\DATA\学生
        SORT  TO  E:\VFP6\DATA-COPY\各系学生  ON  系别,学号/D
        USE  E:\VFP6\DATA-COPY\各系学生   && 打开排序后产生的新文件“各系学生.DBF”
        DISPLAY  ALL
        USE

显示结果:

3.6.2 数据表的索引

排序虽然实现了数据记录的有序排列,但排序结果建立了许多内容相同而只是排列次序不同的数据表文件,因而造成大量数据冗余,浪费了存储空间。且当对数据表进行增、删、改操作时,也会使数据表中的记录变得无序,必须再使用排序命令对数据表进行重新排序,这很不方便,通过创建索引可以解决上述问题。

1. 基本概念

(1)索引 是由指针构成的文件,这些指针逻辑上按照索引关键字的值进行排序。索引文件和表文件分别存储,并且不改变表中记录的物理顺序。实际上,创建索引是创建一个由指向表文件记录的指针构成的文件。如要根据特定顺序处理表记录,可选择一个相应的索引。使用索引不仅可重新安排数据表中已处理记录的顺序,还极大地便利了对表的查看和访问。

索引与排序相比,两者都重新安排原数据表中记录的顺序。不同的是:排序的结果是从物理上改变原表中的记录顺序,产生一个与原表内容相同而只是记录顺序不同的新表;而索引的结果仅是从逻辑上改变系统处理记录的顺序,不产生新表,从而节省了存储空间。

(2)索引的类型 从索引的组织方式上分,VFP中的索引有以下3类。

① 独立索引 是指在索引文件中只能包含一个单一的关键字或者组合关键字的索引。独立索引文件的扩展名为.IDX,它分为压缩索引文件和非压缩索引文件两类。前者能够节省磁盘空间,而且查询速度较快;后者是与xBASE相容的索引文件。

② 结构复合索引 是指在索引文件中可以包含多个索引项的索引,其中每个索引项称为索引标识(Index Tag)。结构复合索引文件的扩展名为.CDX,是VFP中最重要也最常用的一种索引类型,它具有以下几个特点。

● 结构复合索引的文件主名与数据表文件主名相同。

● 在同一索引文件中可以包含多个索引关键字。

● 在打开数据表时自动打开索引文件。

● 在对数据表进行添加、修改、更新、删除等操作时自动维护索引。

③ 非结构复合索引 索引文件的扩展名也是.CDX,但文件主名与数据表文件不相同,它不会随着数据表文件的打开而打开,需要使用单独的打开命令。

复合索引文件全部自动压缩。

(3)索引关键字 是指在数据表中建立索引用的字段或字段表达式,可以是表中的单个字段,也可以是表中几个字段组成的表达式。创建索引文件,就是根据索引关键字值的大小从逻辑上重新安排数据表中各条记录的组织顺序。

(4)索引关键字的类型VFP中的索引关键字可分为以下4种:

① 主索引(Primary Indexes)是指在指定字段或字段表达式中不允许出现重复值的索引,它要求该索引关键字的值必须唯一,不允许重复。例如,学生的学号一般不应该相同,因此在“学生”表中可以为“学号”字段建立主索引来满足这个要求;但不能为“系别”字段建立主索引,因为一个系中肯定不止一个学生,实际情况也是如此。

一个数据库表只能有一个主索引,自由表中没有主索引类型。

② 候选索引(Candidate Indexes)候选索引和主索引具有相同的特性,当某个表已经建立了一个主索引时,可以将表中其他字段或字段表达式的值唯一的索引字段设置为候选索引。例如,在“课程”表中已经为“课程号”字段建立了主索引,如要求每门课程的名称也不能相同,则可以为“课程名”字段建立候选索引。

在数据库表和自由表中可以建立多个候选索引。

③ 唯一索引(Unique Index)指索引文件对每一个特定的关键字只存储一次,而忽略后面出现重复值的记录。唯一索引的“唯一性”指的是索引项的唯一,而不是索引字段值的唯一。例如,在“学生”表中如为“性别”字段建立唯一索引,结果在索引文件中按照该索引项将只存储两条记录,即表中第一个男生记录和第一个女生记录。

在数据库表和自由表中可以建立多个唯一索引。

④ 普通索引(Regular Indexes)指此索引字段的数据允许出现重复值,并且索引项中也允许出现重复值。例如,在“学生”表中应该为“性别”字段和“系别”字段都建立普通索引。

在数据库表和自由表中可以建立多个普通索引。

2. 索引的建立

在所有的索引类型中,结构复合索引是VFP中最重要也是最常用的,本节主要介绍这种类型的索引。如没有特别说明,下面提到的索引均指结构复合索引。

(1)在表设计器中建立索引

利用表设计器不仅可以很方便地创建表结构,也可以为创建索引提供一个非常直观的交互环境。具体操作是:在项目管理器中选定需要建立索引的表,单击“修改”按钮,打开表设计器窗口,选择“索引”选项卡(如图3.48所示)。

图3.48 在表设计器中建立索引

① 在“索引名”文本框中输入索引项的名称作为索引标识,索引名最多10字节。

② 在“类型”下拉列表框中选择索引类型。对于数据库表,有主索引、候选索引、唯一索引和普通索引四种;对于自由表,只有候选索引、唯一索引和普通索引三种。

③ 在“表达式”文本框中输入索引关键字表达式,或者单击文本框右边的“…”按钮,在表达式生成器中建立索引表达式。

索引关键字可以是单个字段,也可以是多个字段的组合;当为多个字段时,通常用字符串运算符“+”联接。如组成表达式的字段类型不相同,必须将它们转换为相同的数据类型。

例如,在“学生”表中,用“系别”和“性别”两个字段组成一个索引项时,相应的索引表达式应表示为“系别+性别”,其含义是:先按系别索引,当“系别”相同时,再按“性别”索引。当用“系别”和“出生日期”两个字段组成一个索引项时,相应的索引表达式应表示为“系别+DTOC(出生日期)”。又如,在“成绩”表中,用“课程号”和“成绩” 两个字段组成一个索引项时,相应的索引表达式应表示为“课程号+STR(成绩,5,1)”。

④ 在“排序”项中单击箭头按钮,选择排序方式:箭头向上表示按索引关键字值的升序(由小到大)排列,箭头向下表示按索引关键字值的降序(由大到小)排列,系统默认为升序。

⑤ 如只对数据表中满足条件的记录建立索引,可以在“筛选”文本框中输入筛选条件,该项一般不使用。

说明:单字段的索引,其索引名可以与字段名相同;组合字段的索引,其索引名最好能反映索引关键字所代表的索引含义。例如,“系别”和“性别” 两个字段组成的索引关键字,其索引名可取为“系别_性别”。

对单字段的索引也可以在“字段”选项卡的“索引”栏中直接建立,方法是:从定义索引的下拉列表框中选择“升序”或“降序”选项,其结果是在该字段上建立一个普通索引,索引名与字段名相同,索引关键字就是对应的字段。若要修改这个结果,可以选择“索引”选项卡。

对于不需要的索引项,可以在“索引”选项卡中将其选定,再单击“删除”按钮。

按上述方法,在“学生”表中分别建立4个索引:学号(主索引)、性别(普通索引)、系别与性别(普通索引)、系别与出生日期(普通索引),结果如图3.48所示。

图3.49显示了在项目管理器中展开“学生”表后的各索引项标志。

图3.49 在项目管理器中查看索引项

索引可以提高查询速度,但是维护索引也要付出代价。对于结构复合索引,当对表进行添加、删除和修改等操作时,系统会自动维护索引,从而降低了添加、删除和修改等操作的速度。所以建立索引也应有所选择,应根据实际需要建立索引,并不是越多越好。

(2)用INDEX命令建立索引

格式1:INDEX ON <索引关键字表达式> TAG <索引标识名>

[UNIQUE|CANDIDATE] [ASCENDING|DESCENDING] [FOR <条件>]

功能:建立结构复合索引。

说明:

① <索引关键字表达式>可以是单个字段,也可以是多个字段组合,其含义同上。

② TAG <索引标识名>表示在复合索引文件中建立一个指定的索引标识。

③ UNIQUE表示建立唯一索引,CANDIDATE表示建立候选索引。不带这两个选项,表示建立普通索引。

④ ASCENDING|DESCENDING表示索引关键字以递增或递减的方式建立索引,默认为升序。

⑤ FOR <条件>表示仅对数据表中满足条件的记录建立索引。

使用INDEX命令只能建立普通索引、唯一索引和候选索引,没有主索引。

若要删除复合索引中的某个索引项,可以使用DELETE TAG命令。

格式2:DELETE TAG ALL |<索引标识名>

功能:从复合索引文件中删除全部索引或指定的索引项。

说明:使用ALL选项将删除复合索引文件中的全部索引项,该复合索引文件将自动被删除。使用<索引标识名>选项只删除指定的索引项。

【例3.32】 用INDEX命令为“学生”表建立结构复合索引,包含4个索引项:学号(候选索引)、性别(普通索引)、系别与性别(普通索引)、系别与出生日期(普通索引)。

        USE  E:\VFP6\DATA\学生
        INDEX  ON  学号  TAG  学号  CANDIDATE
        INDEX  ON  性别  TAG  性别  DESCENDING
        INDEX  ON系别 + 性别  TAG  系别_性别
        INDEX  ON系别 +DTOC(出生日期)  TAG系别_生日
        USE

3. 按索引顺序浏览记录

建立索引后,就可以按照索引关键字值的顺序来显示或处理记录了。如上所述,一个复合索引文件中可以建立多个索引项,每一项代表了处理记录的一种逻辑顺序;但在同一时刻,系统只能使用一种索引顺序。所以在使用索引前,应先指定将要使用的索引项。

(1)菜单方式

在项目管理器中选定“学生”表,单击“浏览”按钮打开浏览窗口,再选择“表|属性”命令,打开图3.50所示的“工作区属性”对话框。在“索引顺序”下拉列表框中选择当前要使用的某个索引项,单击“确定”按钮,浏览窗口中的记录就会按照所选的索引顺序排列。

图3.50 设置索引顺序

依次选择“学号”、“性别”、“系别_性别”和“系别_生日”4种索引,在浏览窗口中的显示结果如图3.51所示。

图3.51 按索引顺序组织记录

在图3.50所示的对话框中,如从“索引顺序”列表中选择“无顺序”选项,则表示不使用任何索引,只按实际输入时的物理顺序来显示或处理记录。

(2)命令方式

格式:SET ORDER TO [TAG <索引标识名>]

功能:在打开的复合索引文件中设置一个索引标识作为主标识,使数据表中的记录按该索引顺序处理。

说明:不带TAG <索引标识名>选项,表示取消使用任何索引。

【例3.33】 接例3.32,假设已在“学生.CDX”复合索引文件中建立了4个索引项,将“性别”和“系别_性别”索引项分别设置为当前索引,并显示“学生”表的记录,最后取消索引。

        CLEAR                           && 清除主窗口中的显示内容
        USE  E:\VFP6\DATA\学生
        SET  ORDER  TO  TAG性别         && 命令方式将“性别”索引项设置为当前索引
        DISPLAY  ALL
        SET  ORDER  TO  TAG系别_性别    && 命令方式将“系别_性别”索引项设置为当前索引
        DISPLAY  ALL
        SET  ORDER  TO                  && 取消索引
        DISPLAY  ALL

显示结果:

3.6.3 数据表的查询

数据表建立之后,虽然可以通过BROWSE,DISPLAY,LIST等命令来查询指定条件的记录,但速度较慢。在数据库应用系统中,一个数据表中的数据量往往非常大,可能有上百条、上千条或更多记录,使用这样的查询命令不能满足应用系统的运行要求。在VFP系统中,当对数据表建立索引以后,可以使用FIND, SEEK等专门的数据表查询命令,实现快速记录指针定位,从而大大提高整个数据库应用系统的运行效率。

1. FIND命令

格式:FIND <字符串>|<数值>

功能:在索引文件中找到索引关键字值与指定字符串或数值相符的第1条记录,并将记录指针指向它。

说明:

① 只有对已经建立过索引的数据表文件才能使用该命令,并且索引文件的关键字必须是要查找的字段。

② 该命令只能查找字符型和数值型的索引关键字,字符串可以省略定界符。

③ 当通过字符型内存变量检索时,命令中必须使用宏替换“&”,表示按内存变量的内容检索。

④ 检索到匹配的记录时,记录指针将指向该记录。测试函数FOUND( )返回值为.T.,EOF( )函数返回值为.F.,RECNO( )函数返回对应的记录号;否则,FOUND( )函数返回值为.F.,EOF( )函数返回值为.T.,此时,RECNO( )函数返回末记录号加1的数值。

【例3.34】 假设已在“学生”表中按学号建立索引,用FIND命令进行查询。

        USE  E:\VFP6\DATA\学生
        SET  ORDER  TO  TAG学号
        FIND  01040501
        ?RECNO()                && 结果显示为8
        DISPLAY

显示结果:

        XH="01060301"
        FIND  &XH
        ?FOUND()               && 结果显示为 .T.
        DISPLAY

显示结果:

2. SEEK命令

格式:SEEK <表达式> [ORDER [TAG] <索引标识名>][ASCENDING|DECENDING]

功能:在索引文件中查找关键字内容与表达式相同的第1条记录。

说明:

① 只有对已经建立过索引的数据表文件才能使用该命令,并且索引文件的关键字必须是要查找的字段。

② 该命令可以处理任何类型的关键字表达式。当查找字符型常量时,需要使用字符串定界符。

③ 可以直接查找字符型、数值型、日期型、逻辑型内存变量,不需要任何变换。

④ ORDER选项指定按复合索引中的哪个索引项定位。

⑤ ASCENDING|DESCENDING选项指定以升序或降序搜索数据表。当表中的记录很多时,根据索引关键字的值决定从前面开始查找还是从后面开始查找,可以提高查询的速度。

【例3.35】 假设已在“学生”表中按“性别”及“系别_性别”建立索引,用SEEK命令进行查询。

        USE  E:\VFP6\DATA\学生
        SEEK  "女"  ORDER  性别
        DISPLAY

显示结果:

        SET ORDER TO TAG系别_性别
        SEEK  "历史"+"男"
        ?FOUND()                && 结果显示为 .T.
        DISPLAY

显示结果:

        SEEK  "历史"+"女"
        ?FOUND()                && 结果显示为 .F.

说明:

① FIND命令和SEEK命令只能用于已经建立过索引的数据表文件记录的查询。

② 在3.4.2节有关记录定位的内容中介绍过LOCATE命令,它按指定的条件在当前数据表中查找记录,若找到,就将记录指针指向该记录。如数据表文件没有使用索引,则LOCATE命令就按物理顺序检索记录;如数据表文件使用了索引,则LOCATE命令就按索引顺序检索记录。

3.6.4 数据表的统计与汇总

在VFP中,不仅可以对数据表中的记录进行检索,还可以对表中相应的记录进行统计,对数值型数据可以进行求和、求平均值及分类汇总等计算。

1. 数据表的统计

(1)计数命令

格式:COUNT [<范围>] [FOR <条件>] [WHILE <条件>] [TO <内存变量名>]

功能:在当前数据表文件中,统计指定范围内满足条件的记录个数。

说明:

① 如默认全部选项,则统计数据表中的全部记录个数。

② TO <内存变量名>选项指定内存变量,用来存放统计结果。如没有此项,统计结果只显示不保存。

【例3.36】 分别统计“学生”表中所有的学生人数和没有贷款的学生人数。

        USE  E:\VFP6\DATA\学生
        COUNT  TO  ALL_STUDENT
        ? "学生总人数为",ALL_STUDENT
        COUNT  FOR  贷款否  TO  NON_LOAN
        ? "没有贷款的学生人数为"+STR(NON_LOAN,3)

显示结果:

学生总人数为10

没有贷款的学生人数为4

(2)求和命令

格式:SUM [<字段表达式表>][<范围>] [TO <内存变量名表>|

TO ARRAY <数组名>] [FOR <条件>] [WHILE<条件>]

功能:对当前数据表中满足条件的记录根据指定的数值型字段表达式按列求和。

说明:

① 没有任何选项时,对当前数据表中的所有数值型字段求和。

② <字段表达式表>指定求和的各个字段,各字段之间用逗号分隔。若没有此项,则对全部数值型字段分别按列求和。

③ TO <内存变量名表>指定保存求和结果的各内存变量,其数目必须与求和字段的数目相同。TO ARRAY <数组名>指定保存求和结果的数组,该数组必须已经存在。

【例3.37】 统计“成绩”表中学号为“01020215”的学生各门课程的总成绩。

        USE  E:\VFP6\DATA\成绩
        SUM  成绩  FOR  学号="01020215"            && 结果为  247.50

(3)求平均值命令

格式:AVERAGE [<字段表达式表>] [<范围>] [TO <内存变量名表>|

TO ARRAY <数组名>] [FOR <条件>] [WHILE <条件>]

功能:对当前数据表中满足条件的记录按指定的数值型字段求平均值。

说明:各选项的含义与SUM命令相同。

【例3.38】 求“成绩”表中学号为“01020215”的学生的平均分。

        USE  E:\VFP6\DATA\成绩
        AVERAGE  成绩  FOR  学号="01020215"       && 结果为  82.50

2. 数据表的分类汇总

数据表的分类汇总也叫做同类项合并或分类求和,是对数据表中的数值型字段按照排序或索引关键字值的不同分类,按组分别求和。

格式:TOTAL ON <汇总关键字> TO <表文件名> [FIELDS <字段名表>]

[<范围>] [FOR <条件>] [WHILE<条件>]

功能:在当前数据表的指定范围内,以汇总关键字的值分类,对满足条件的记录按指定的数值字段求和,并将结果保存在新的表文件中。

说明:

① 使用TOTAL命令前,当前表必须按<汇总关键字>进行排序或索引。

② 如不指定范围、条件和FIELDS选项,则对全部记录的所有数值型字段按关键字值进行分类求和;否则,只对指定范围内满足条件的记录按指定的字段分类求和。

③ 分类求和的结果将产生一个新的表文件(.DBF),其结构与当前表文件相同,但不包括备注型字段。当前表中关键字值相同的一类记录,在新表中只有一条记录,其数值型字段的值是同类记录之和。如带FIELDS选项,则其他没有指定的数值型字段和其他类型的字段将是此类记录的第一条记录相应的字段值。

④ 数值型字段求和时,如求和结果的长度超过该字段定义的宽度,系统会自动修改新表的数值字段宽度以存放该结果。

【例3.39】 对“成绩”表中的成绩按“学号”进行分类汇总(即求每个学生各门课程的总成绩)。

        USE  E:\VFP6\DATA\成绩
        INDEX  ON  学号  TAG  学号
        TOTAL  ON  学号  TO  E:\VFP6\DATA-COPY\成绩汇总
        USE  E:\VFP6\DATA-COPY\成绩汇总
        LIST
        USE

显示结果:

由显示结果可以看出,在分类汇总生成的新表中“课程号”字段已经没有实际意义了。

3.7 数据字典的建立

在VFP中,数据库文件(.DBC)文件不仅可用于组织和管理VFP中的表(.DBF),还可作为一个数据字典来存储和管理有关表、记录和字段的规则、默认值、触发器、表间关系等。数据字典的各种功能使得对数据库的设计和修改更加灵活。VFP的数据字典具有如下功能:

● 设置长表名和长字段名。

● 设置主关键字和候选关键字。

● 指定字段的输入掩码和显示格式。

● 设置字段的默认值。

● 设置字段的标题。

● 创建字段和记录的有效性规则。

● 设置触发器。

● 为字段、表和数据库添加注释。

● 创建数据库表间的永久关系。

● 创建存储过程。

一些数据词典的功能(如长字段名、主关键字、默认值、字段规则、触发器等)可以在建立数据库表的过程中创建。

3.7.1 设置表的字段属性

在VFP中创建数据库表时,可以为数据库表的字段设置一些自由表所没有的属性。在数据库表的表设计器中有一个显示组框,在该组框中可以定义字段输入的掩码、显示的格式和字段标题等。

1. 输入掩码

输入掩码是指定义字段中的值必须遵守的标点、空格和其他格式要求,以限制或控制用户输入的数据格式,屏蔽非法输入,从而减少人为的数据输入错误,保证输入的字段数据具有统一的风格,提高输入的效率。例如,在“课程”表中,如规定课程号的格式由字母JC和1~3位数字组成(此时该字段的宽度应设置为5),则可在表设计器中选中“课程号”字段,然后在“输入掩码”文本框中输入“JC999”,如图3.52所示。

图3.52 设置字段的输入掩码

2. 格式

格式实质上就是一种输出掩码,它决定了字段在浏览窗口、表单、报表等界面中的显示样式。例如,在“课程”表中,如要求凡是课程名中带字母的必须一律显示为大写字母,则格式可以定义为20个“!”(假设课程名的数据宽度为20)。这样在输入课程名数据时,只要遇到小写字母,系统就会自动转换为大写字母。

表3.7所示为常用掩码及其含义。

表3.7 常用掩码及其含义

3. 字段标题

在数据库表中允许字段名最多使用128字节,即长字段名,但使用时可能会很不方便。一般字段名都比较简短,但为了在浏览窗口、表单或报表中显示时让其他人更容易了解该字段所代表的含义,可以为字段指定一个字符串作为在浏览窗口、表单或报表中显示时的标题文字。如没有为字段设置标题,就显示相应的字段名。所以,当字段名是英文或缩写时,通过指定标题可以使界面更友好。例如,在“学生”表中,可以为“系别”字段指定标题“学生所在系”,在浏览窗口中浏览学生表信息时,原来的列标头“系别”就会变为“学生所在系”,如图3.53所示。

图3.53 设置字段标题

需要注意的是,字段标题仅仅改变在浏览窗口、表单或报表中显示表记录时字段名称栏所显示的文字内容,在程序中引用该字段变量时仍应用其字段名。

4. 字段注释

在数据库表中可以为每个字段加上一些详细的注解,或一些说明性的文字,使得数据表更容易被人理解,便于日后其他人对数据表进行维护。例如,在“成绩”表中,可以为“成绩”字段加上注释:“成绩字段是指平时测验、期中测验和期末测验的总评成绩”。此时,在“项目管理器”中打开“成绩”表,选中“成绩”字段后,窗口底部的“说明”栏中就会显示该注释信息,如图3.54所示。

图3.54 为字段添加注释

除了能给表中的各个字段添加注释外,还可以为整个数据库表添加注释,只要从表设计器中选择“表”选项卡,在“表注释”编辑框中输入需要的注释内容即可。当在项目管理器中选中该表时,就会在底部的“说明”栏中显示出该表的注释信息。

3.7.2 设置表的有效性规则

数据库表的有效性规则包括字段级规则和记录级规则两种,分别用来控制输入数据库表的某个字段和某条记录中的信息类型是否符合指定的要求。字段级和记录级规则将把所输入的值与所定义的规则表达式进行比较,只有输入的值满足规则要求时才接受,否则就拒绝,从而保证了数据的有效性和可靠性,大大减少数据错误。

字段规则可以在表设计器“字段”选项卡的“字段有效性”组框中定义,记录规则在“表”选项卡的“记录有效性”组框中定义。

1. 字段级规则

设置字段的有效性规则,可以控制输入字段中的数据类型,以便检验输入的数据是否正确。字段级规则在输入字段值或改变字段值时才发生作用。例如,在“学生”表中为保证输入的学生性别只能是“男”或“女”两个值,可以为“性别”字段建立字段级规则,具体方法如下:

(1)选择“字段”选项卡,然后选中要定义规则的字段,如“性别”字段。

(2)在“字段有效性”组框的“规则”文本框中输入一个逻辑表达式(即规则),也可以单击“…”按钮,在表达式生成器中创建该表达式:性别 $ "男女"。

(3)在“信息”文本框中输入违反有效性规则时的提示信息(注意,信息是字符串表达式,必须加字符串定界符):"性别必须是‘男’或‘女’,不接受其他值。"。

如没有输入提示信息,系统将显示默认的提示信息。

按图3.55所示设置字段规则和相应的提示信息后,当用户将某个学生的性别“男”误输入为“难”时,系统即显示图3.56所示的提示框,并拒绝接受该数据。

图3.55 定义字段有效性规则

图3.56 违反字段有效性规则时的提示信息

2. 默认值

为字段定义一个默认值后,在创建新记录时系统能够自动为该字段填入默认值,从而简化操作,提高数据输入的速度。默认值可以是任何有效的表达式,但表达式的返回值必须和该字段的数据类型一致。

例如,在“学生”表中,如男生居多,就可以为“性别”字段设置默认值“男”,见图3.55。这样,在“学生”表中每增加一条新记录,“性别”字段就会自动取值为“男”;如是一条女生记录,可将记录值“男”改为“女”。

3. 记录级规则

使用记录的有效性规则,可以控制用户输入记录中的信息类型,检验输入的整条记录是否符合要求。字段级有效性规则只对应一个字段,记录级有效性规则通常用来比较同一条记录中的两个或两个以上字段值,以确保它们遵守在数据库中建立的有效性规则。记录的有效性规则通常在输入或修改记录时激活,在删除记录时一般不起作用。

例如,在“学生”表中输入记录时要求“学号必须满8位,并且性别只能是‘男’或‘女’两个值”,这种情况下就可以为“学生”表建立记录级规则,具体方法如下:

(1)选择“表”选项卡,在“记录有效性”组框的“规则”文本框中输入一个逻辑表达式,也可以单击“…”按钮,在表达式生成器中创建该表达式:

        LEN(ALLTRIM(学号))=8  .AND.  性别 $"男女"

(2)在“信息”文本框中输入如下提示信息:

      "学生的学号必须是8位,并且性别只能取‘男’或‘女’两个值。"

如没有输入提示信息,则违反记录有效性规则时系统将显示默认的提示信息。

按图3.57所示设置记录规则和相应的提示信息后,在输入学生记录时,只要违反了规则中的任意一个条件,系统就会显示出错信息,并拒绝接受该条记录。

图3.57 定义记录有效性规则

3.7.3 设置触发器

所谓触发器,是指在数据库表中对记录进行插入、删除、更新等操作时,系统自动启动一个程序来完成指定的任务。在VFP中有3种形式的触发器。

(1)插入触发器 是在数据库表中插入记录时所触发的检测程序,该程序可以是表达式或自定义函数。检测结果为真时,接受插入的记录;否则,插入的记录将不被存储。

(2)更新触发器 是在数据库表中修改记录后按回车键时所触发的检测程序,该程序可以是表达式或自定义函数。如检测结果为真,则保存修改后的记录;否则,不保存修改后的记录,同时还原修改之前的记录值。

(3)删除触发器 是在数据库表中删除记录时所激发的检测程序,该程序可以是表达式或自定义函数。如检测结果为真,该记录可以被删除;如返回值为假,则该记录禁止被删除。

这3种触发器均可以在表设计器中创建。

例如,在教学管理数据库的“学生”表中,为避免用户不慎删除记录,可以创建一个简单的删除触发器,当用户执行删除记录操作时,触发器显示提示信息,并让用户选择是否删除。创建删除触发器的操作如下:在表设计器中选择“表”选项卡,然后在“触发器”组框中的“删除触发器”文本框中输入表达式:

      MESSAGEBOX("真的要删除吗?",275, "提示信息")=6

当用户删除表中的记录时,VFP便激活该触发器,显示图3.58所示的信息。选择“是”,系统就删除这条记录;选择“否”或“取消”,记录将不被删除。

图3.58 使用触发器

3.7.4 永久关系的创建

永久关系是数据库表之间的关系,它存储在数据库文件(.DBC)中。永久关系的功能主要表现在:

● 在“查询设计器”和“视图设计器”中,自动作为默认联接条件。

● 在“数据库设计器”中,显示为联系数据表索引的关系线。

● 作为表单和报表的默认关系,在“数据环境设计器”中显示。

● 用来存储参照完整性信息。

在数据库中建立关系的两个表通常具有公共字段或语义相关的字段。其中,包含主关键字段(即建立主索引的字段)的表称为父表,另一个包含外部关键字段的表称为子表。

1. 关系的建立

在数据库设计器中可以很方便地建立永久关系,方法是:在“数据库设计器”中选中父表中的主索引名,然后按住鼠标左键,并拖动鼠标到子表的对应索引名上,鼠标箭头会变为小矩形状。松开鼠标,即在建立关系的两个表之间出现一条联系数据表索引的直线,永久关系就建好了。

以“教学管理”数据库为例,在“学生”表中以“学号”为主关键字段,建立索引名为“学号”的主索引;在“课程”表中,以“课程号”为主关键字段,建立名为“课程号”的主索引;在“成绩”表中,分别以“学号”和“课程号”作为索引关键字,建立名为“学号”和“课程号”的两个普通索引。现在分别以“学生”表和“课程”表为父表,“成绩”表为子表,在“学生”表和“成绩”表之间、“课程”表和“成绩”表之间创建两个永久关系。

打开项目管理器,选择“教学管理”数据库,双击它,或者单击“修改”按钮,打开数据库设计器,如图3.59所示。先用鼠标选中“学生”表中的“学号”主索引,然后按住鼠标左键,并拖动鼠标到“成绩”表的“学号”索引,鼠标箭头变为小矩形状。松开鼠标后,在这两个表之间出现一条黑色的关系连线。

图3.59 数据库设计器

用同样的方法可以建立“课程”表和“成绩”表之间的关系,结果如图3.60所示。

图3.60 表之间的关系

在建立关系时,系统会自动根据索引类型来决定关系的类型。若子表为普通索引,则两表之间建立的是一对多的关系,如图3.60所示;若子表也为主索引,则两表之间建立的就是一对一的关系。

2. 关系的编辑

在数据库设计器中可以对已建立的关系重新编辑修改,方法是:右击要修改的关系线,线条变粗,从快捷菜单中选择“编辑关系”命令,出现如图3.61所示的“编辑关系”对话框。只要从下拉列表框中重新选择表或相关表的索引名即可修改关系。

图3.61 “编辑关系”对话框

3. 关系的删除

如要删除数据库表之间的永久关系,可在数据库设计器中单击两表之间的关系线,选中它(关系线变粗),按Delete键即可。

3.7.5 参照完整性的设置

参照完整性是指建立一组规则,当用户插入、更新或删除一个数据表中的记录时,通过参照引用另一个与之有关系的数据表中的记录,来检查对当前表的数据操作是否正确。在VFP中,对建立了关系的两个数据库表,通过实施参照完整性规则,可以确保当父表中没有关联记录时,记录不得添加到子表中;当因改变主表的值而导致子表中出现孤立记录时,主表的值不能改变;当主表记录在子表中有匹配记录时,该主表记录不能删除。

在VFP中,利用参照完整性生成器可以帮助确定要实施的规则类型、要实施规则的表,以及能导致VFP检查参照完整性规则的系统事件。

在建立参照完整性之前,先打开数据库设计器,选择“数据库|清理数据库”命令,再选择“数据库|编辑参照完整性”命令,出现图3.62所示的“参照完整性生成器”窗口,其中包含“更新规则”、“删除规则”和“插入规则”三个选项卡,分别用来定义更新规则、删除规则和插入规则。

图3.62 “参照完整性生成器”窗口

(1)更新规则规定了当更新父表中的主关键字值时,如何处理子表中的相关记录。

(2)删除规则规定了当删除父表中的记录时,如何处理子表中的相关记录。

(3)插入规则规定了当在子表中插入或更新记录时,是否进行参照完整性检查。

可以根据需要选择一种合适的参照完整性规则,然后单击“确定”按钮,完成设置。例如,在“教学管理”数据库中可以建立图3.62所示的参照完整性规则。

3.7.6 存储过程

存储过程是存储在数据库文件(.DBC)中的VFP代码,是专门操作数据库中数据的代码过程。在打开一个数据库时,它们便加载到了内存中。因此,存储过程可以提高数据库性能。

使用存储过程主要是为了创建用户自定义函数,字段级规则和记录级规则将引用这些函数。当把一个用户自定义函数作为存储过程保存在数据库中时,函数的代码将保存在.DBC文件中,并且在移动数据库时自动随数据库移动。使用存储过程可以不必在数据库文件之外管理用户自定义函数,使得应用程序更容易管理。

本节详细介绍了VFP中有关数据字典的各种功能,需要说明的是:这些功能都是数据库表所特有的,如将数据库表移出数据库,成为自由表后,这些特有的属性将会全部丢失。如要将其添加到数据库中,必须重新创建这些功能。

3.8 多数据表的操作

前面所有的操作都是对一个数据表进行的,在实际工作中,常常需要同时使用几个数据表中的数据,这就涉及多数据表的操作问题。

3.8.1 工作区的选择

1. 工作区

在VFP中,对数据表进行操作之前,必须先将其打开,即从外部存储器调入内存工作区,然后才能使用。VFP系统允许在32767个工作区中打开和操作数据表,但同一时刻一个工作区只能打开一个数据表文件。如在同一工作区中打开了另一个数据表文件,则系统自动关闭前一个已打开的数据表文件。如需要同时使用多个数据表文件,则需要在不同的工作区中分别打开。

在VFP中,每个工作区都有一个编号,称为工作区号,用1, 2, 3, 4等表示,对1~10号工作区,还可以用A~J等10个英文字母来表示。系统默认在第1个工作区中工作。以前打开数据表时,虽然没有指定工作区,但实际上都是在第1个工作区打开和操作表的。

2. 选择工作区

使用SELECT命令可以选择需要使用的工作区。

格式:SELECT <工作区号|别名|0>

功能:选择需要使用的工作区。

说明:

① 别名是指该数据表文件的另一个更便于阅读、操作或记忆的文件名。可以在用USE命令打开数据表时定义该表的别名,相应的命令格式:

USE <数据表文件名> ALIAS <数据表文件的别名>

② 如在某个工作区中打开数据表文件的同时,为该文件定义了别名,则可以使用别名代表该工作区进行操作;若没有定义别名,则使用数据表文件名代表该工作区。

③ SELECT 0表示让系统自动选择工作区号最小的空闲工作区作为当前工作区。

④ 执行SELECT命令后,最后选择的工作区为当前工作区。

在每个工作区打开的数据表文件都有各自独立的记录指针。通常,在一个工作区中移动记录指针时不会影响其他工作区的记录指针。

对当前工作区中的数据表可以直接进行读、写等任何操作;而对于其他工作区中的数据表,则只能读取该区记录指针指向的当前记录,并且要用<别名>.<字段名>或<别名>-><字段名>的格式来指定其他工作区的字段。

注意:在某个工作区打开数据表之后,返回该工作区时不必再次打开同一个数据表。

【例3.40】 在不同的工作区打开“学生”表和“成绩”表,然后显示第1条记录所对应的学号、姓名、系别、课程号和成绩信息。

        SELECT  1
        USE  E:\VFP6\DATA\学生  ALIAS  XS  && 在1号工作区打开“学生”表,并指定别名XS
        ?RECNO()                        && 结果为 1,说明1号工作区指针指向第1条记录
        SELECT 2
        USE  E:\VFP6\DATA\成绩  ALIAS  CJ  && 在2号工作区打开“成绩”表,并指定别名CJ
        ?RECNO()                        && 结果为 1,说明2号工作区指针指向第1条记录
        SELECT  XS                      && 返回1号工作区
        DISPLAY  学号,姓名,系别,B->学号,B->课程号,B->成绩
        GO  5                           && 将1号工作区指针指向第5条记录
        SELECT  B                       && 返回2号工作区
        ?RECNO()                        && 结果为1,说明2号工作区指针没有变动
        SELECT A&& 返回1号工作区
        DISPLAY学号,姓名,系别,B.学号,B.课程号,B.成绩
        CLOSE  ALL                      && 关闭所有工作区中的所有文件

显示结果:

从这个例子看到,刚打开“学生”表和“成绩”表时,它们各自的记录指针都是指向第1条记录(第1个DISPLAY命令的显示结果)。当在“学生”表(1号工作区)中将记录指针移到第5条记录时,“成绩”表(2号工作区)中的记录指针并没有随之移动,仍指向第1条记录(第2个DISPLAY命令的显示结果),也就是说,移动当前工作区的记录指针并不能带动其他工作区的记录指针同步移动。要保持两个工作区的记录指针同步移动,必须建立工作区之间数据表的关联。

也可以在USE命令中直接指定在哪个工作区中打开表,例如:

        USE  E:\VFP6\DATA\学生  IN  1  ALIAS  XS
        USE  E:\VFP6\DATA\课程  IN  2  ALIAS  KC
        USE  E:\VFP6\DATA\成绩  IN  3  ALIAS  CJ

执行上述命令后,将分别在工作区1, 2, 3中打开“学生”表、“课程”表和“成绩”表,同时为它们指定相应的别名。

3.8.2 数据表的联接

1. 数据表的关联

例3.40表明,每个工作区都有各自独立的记录指针,通常情况下这些指针是不会同步移动的。通过在数据表之间建立关联,可以让两个数据表的记录指针同步移动。这种关联仅在两个表之间建立一种逻辑关系,即建立记录指针之间的联系,而不产生一个新的数据表文件,所以这种操作也称为数据表间的逻辑联接。使用SET RELATION命令可以建立数据表之间的关联。

格式:SET RELATION TO [<关键字表达式1> INTO <工作区号>|<别名>]

[,<关键字表达式2> INTO <工作区号>|<别名>…] [ADDITIVE]

功能:当前工作区中的数据表文件与其他工作区中的数据表文件通过关键字建立关联。

说明:

① 关键字表达式的值必须是相关联的两个数据表共同具有的字段,并且<别名>表文件必须已经按关键字表达式建立了索引文件并处于打开状态。

② 在一条SET RELATION命令中可以创建单个父表与多个子表之间的关联,各个关系之间用逗号隔开。

③ ADDITIVE选项表示用本命令建立关联时仍然保留该工作区与其他工作区已经建立的关联。当要建立多个关联时,必须使用ADDITIVE选项。

④ 两个数据表建立关联后,当前表(父表)的记录指针移到某一记录时,被关联的数据表(子表)的记录指针也自动指向关键字值相同的记录上。如在子表中没有找到匹配的记录,指针将指向子表文件尾,即函数EOF( )的值为.T.。

⑤ 当子表具有多个关键字值相同的记录时,指针只指向关键字值相同的第1条记录。要找到关键字值相同的其他记录,可以使用命令:

SET SKIP TO <别名1> [,<别名2>…]

⑥ 不带参数的SET RELATON TO命令表示删除当前工作区中所有的关系。

⑦ 如需要切断父表与子表之间的关联,可以使用命令:

SET RELATION OFF INTO <工作区号>|<别名>

【例3.41】 在“学生”表与“成绩”表之间建立关联,并显示学号、姓名、系别、课程号和成绩等字段的内容。

        SELECT  2
        USE  E:\VFP6\DATA\成绩
        INDEX  ON  学号TAG  学号    && 在“成绩”表中以“学号”为关键字建立索引
        SELECT  1
        USE  E:\VFP6\DATA\学生
        SET RELATION TO学号INTO B   &&“学生”表作为父表,“成绩”表作为子表,建立关联
        DISPLAY  ALL  学号,姓名,系别,B->学号,B->课程号,B->成绩
        SET  SKIP  TO  B
        DISPLAY  ALL  学号,姓名,系别,B->学号,B->课程号,B->成绩
        GO  5                       && 将1号工作区记录指针指向第5条记录
        DISPLAY  学号,姓名,系别,B->学号,B->课程号,B->成绩
        CLOSE  ALL

显示结果:

从这个例子可以看出,在两个表之间建立逻辑关联后,记录指针就可以同步移动,保证了显示记录内容的一致性。

表之间的这种逻辑联接是一种临时关系,会随着数据表的关闭而自动关闭,下次再使用时必须重新建立。3.7.4节中介绍的数据库表之间的永久关系则是存储在数据库文件(.DBC)中的,随着数据库的打开而打开,每次使用时不需要重新建立。但永久关系不能控制不同工作区中记录指针的联动。

2. 数据表的物理联接

数据表之间的物理联接是指将两个表文件联接生成一个新的表文件,新表文件中的字段从两个表中选取。使用JOIN命令可以在两个数据表之间建立物理联接。

格式: JOIN WITH <工作区号>|<别名> TO <新表文件名>

[FIELDS <字段名表>] FOR <联接条件>

功能:将不同工作区中的两个表文件联接生成一个新的表文件。

说明:

① 生成的新表文件扩展名仍为.DBF。

② FIELDS <字段名表>指定新表文件中所包含的字段,这些字段必须是原来两个表文件中的字段。如无此选项,新表文件中的字段将是原来两个表中的所有字段,字段名相同的只保留一项。

③ FOR <联接条件> 指定两个表文件联接的条件,只有满足条件的记录才联接。

执行该命令后,当前表文件从第1条记录开始,与联接表的全部记录逐个比较。若满足联接条件,就把这两条记录联接起来,作为一条记录存放到新表文件中;若不满足联接条件,则进行下一条记录的比较。然后,当前表文件的记录指针指向下一条记录,重复上述过程,直到当前表文件中的全部记录处理完毕。联接过程中,如当前表文件的某一条记录在联接表中找不到相匹配的记录,则不在新表文件中生成记录。如两个表的记录数分别为M和N,则新数据表的记录数最多为M×N条。

【例3.42】 将“学生”表和“成绩”表通过“学号”联接起来,生成新的数据表文件“学生-成绩”,新表文件中包含如下字段:学号、姓名、系别、课程号、成绩。

        SELECT  B
        USE  E:\VFP6\DATA\成绩
        SELECT  A
        USE  E:\VFP6\DATA\学生
        JOIN  WITH  B  TO  E:\VFP6\DATA-COPY\学生-成绩
        FIELDS  学号,姓名,系别,B.课程号,B.成绩  FOR学号=B.学号
        SELECT  C
        USE  E:\VFP6\DATA-COPY\学生-成绩
        LIST
        CLOSE  ALL

显示结果:

习题3

3.1 思考题

1. 在VFP中,项目管理器的作用是什么?

2. 什么是自由表和数据库表?如何将自由表转为数据库表?如何将数据库表转为自由表?

3. 如何在项目中添加或新建数据库?如何在数据库中添加或新建数据表?

4. 向表中添加记录有几种方法?

5. 筛选字段或记录的作用是什么?如何对字段或记录进行筛选?

6. 什么是索引?索引和排序有何区别?

7. 索引关键字的类型有哪几种?

8. 在VFP中有哪些检索记录的命令?使用时有什么要求?

9. 什么是数据字典?在VFP中,数据字典有哪些功能?

10. 什么是有效性规则?如何创建字段级和记录级规则?

11. 参照完整性有何作用?

12. 数据表之间的永久关系和临时关系的区别是什么?

13. 有哪两种删除记录的方法?它们的区别是什么?

14. 为什么要使用多工作区?如何选择当前工作区?

3.2 选择题

1. 打开数据库的命令是(  )。

(A)USE DATABASE

(B)OPEN DATABASE

(C)USE

(D)OPEN

2. 下面关于结构复合索引的特点中不正确的是(  )。

(A)索引文件主名与表文件同名

(B)索引文件随着表文件的打开而打开

(C)对表进行添加、修改、删除等操作时,索引结果会自动更新

(D)一个索引文件中只能包含一个索引项

3. 假设数据表文件的当前记录号为50,将记录指针移到35号的命令是(  )。

(A)SKIP -35

(B)SKIP 35

(C)SKIP 15

(D)SKIP -15

4. 对一个数据表文件执行了LIST命令之后,再执行?EOF( )命令的结果是(  )。

(A).F.

(B).T.

(C)0

(D)l

5. ZAP命令的作用是(  )。

(A)将当前工作区内打开的数据表文件中所有记录加上删除标记

(B)将当前工作区内打开的数据表文件删除

(C)将当前工作区内打开的数据表文件中所有记录做物理删除

(D)将当前工作区内打开的数据表文件结构删除

6. 在VFP中定义数据表结构时,有一个数值型字段要求保存4位整数、2位小数,并且其值可能为负,则该字段的宽度应定义为(  )

(A)8

(B)7

(C)6

(D)5

7. 某“职工”表中有职称(C)和工资(N)两个字段,计算所有职称为正教授或副教授的工资总额,并将结果赋给内存变量ZGZ,应使用命令(  )

(A)SUM工资TO ZGZ FOR职称="副教授" .AND. "教授"

(B)SUM工资TO ZGZ FOR职称="副教授" .OR. "教授"

(C)SUM工资TO ZGZ FOR职称="副教授" .AND. 职称="教授"

(D)SUM工资TO ZGZ FOR职称="副教授" .OR. 职称="教授"

8. 在职工工资数据表中,对工资字段按升序索引。若使用该索引顺序,执行GO TOP命令后,当前记录号应为(  )。

(A)1

(B)0

(C)工资值最低的记录号

(D)工资值最高的记录号

9. 若已打开“学生.DBF”表文件,要统计该表中的记录数,应使用的命令是(  )。

(A)TOTAL

(B)SUM

(C)COUNT

(D)AVERAGE

10. 在职工.DBF数据表中,已经对“职称”字段建立了索引,现在要查找职称为教授的职工,应该用命令(  )。

(A)LOCATE职称="教授"

(B)FIND职称="教授"

(C)FIND教授

(D)SEEK职称="教授"

11. 某数据表中定义了1个备注型字段和1个通用型字段,则相应的.FPT备注文件个数是(  )。

(A)0

(B)1

(C)2

(D)不能确定

12. 下面关于排序和索引的叙述中正确的是(  )。

(A)排序和索引操作的结果都会生成一个新的数据表文件

(B)排序和索引操作的结果都不会改变原数据表中的记录顺序

(C)排序和索引操作的结果都会改变原数据表中的记录顺序

(D)排序和索引操作都可以指定多个关键字表达式

13. 在VFP中,自由表和数据库表之间的关系是(  )。

(A)自由表和数据库表可以相互转换,但数据库表转换为自由表后将丢失某些属性

(B)自由表和数据库表可以相互转换,且数据库表转换为自由表后没有任何改变

(C)数据库表可以转换为自由表,但自由表不能转换为数据库表

(D)自由表可以转换为数据库表,但数据库表不能转换为自由表

14. 数据表STUDENT.DBF中有学号(C)和出生年月(D)两个字段,下列索引表达式正确的是(  )。

(A)学号 + CTOD(出生年月)

(B)学号 + 出生年月

(C)学号 +"出生年月"

(D)学号 + DTOC(出生年月)

15. 删除某个数据表的备注文件后(  )。

(A)无法打开该数据表

(B)可以打开数据表,但不能查看其中的备注型字段内容

(C)可以打开数据表,但备注型字段丢失

(D)对数据表没有任何影响

3.3 填空题

1. 职工数据表中有年龄(N,2)和性别(C,2)两个字段,找出所有40岁女职工和50岁男职工的记录的查找条件是______。

2. 教材数据表文件中,有字符型字段“编号”,要求将编号中第2个字母为T的记录逻辑删除,应使用命令______。

3. 如打开一个空数据表文件,用函数RECNO( )测试,其结果一定是______。

4. 执行下列命令后,表DB1的当前记录为______,表DB2的当前记录为______。

        SELECT  1
        USE  DB1
        SELECT  2
        USE  DB2
        SELECT  1
        SKIP  5

5. 数据表由______和______两部分组成。

6. 内存变量“成绩”与当前数据表“CJ.DBF”中的字段变量“成绩”同名,要将当前记录中“成绩”字段的值存入内存变量“成绩”中,应使用的命令是______。

7. 如当前数据表中有10条记录,当前记录号为1,则执行命令SKIP -1后,再执行命令?RECNO( ),结果是______。

8. 在不同工作区之间相互切换时,应使用命令______。

9. 在数据表中,图片型数据应存储在______字段中。

10. 在一个数据库表中,______索引只能有一个,其他索引可以有多个。

3.4 上机练习题

1. 创建项目、数据库和数据表。要求:

(1)在E盘上建立工作目录“E:\VFP练习”和“E:\VFP练习\数据”。

(2)创建名为“档案管理.PJX”的项目文件,保存在“E:\VFP练习”中。

(3)在“档案管理”项目中创建名为“职工档案.DBC”的数据库文件,保存在“E:\VFP练习”中。

(4)在“职工档案”数据库中创建一个名为“职工.DBF”的数据库表,保存在“E:\VFP练习\数据”文件夹中。利用表设计器建立表结构,并输入记录,内容如表3-8所示。

表3.8 职 工 表

说明:表中第一行上方文字表示字段名,下方字符的第1位表示数据类型,第2位表示数据宽度,第3位表示数值型数据的小数位数。简历和照片的内容可自己定义。

(5)创建一个名为“工资.DBF”的自由表,保存在“E:\VFP练习\数据”文件夹中。利用表设计器建立表结构,如表3-9所示(内容暂不输入)。

表3.9 工资表

(6)将“工资”表添加到“职工档案”数据库中,使其成为数据库表。

2. 编辑数据表记录。

(1)从职工表中将职工号、姓名和基本工资3个字段的内容追加到工资表中。

(2)在“工资”表中输入奖金、补贴和水电费3个字段的内容。

(3)用“表”菜单或REPLACE命令计算“工资”表中的实发工资。

(4)打开浏览窗口,显示“职工”表记录,并在最后增加2条新记录,内容自己定义。

(5)逻辑删除“职工”表中新增加的2条记录,再将其物理删除。

3. 浏览记录

按要求分别用菜单或命令方式浏览或显示“职工”表中的记录。

(1)浏览或显示所有记录。

(2)浏览或显示所有男职工的姓名、职称、部门和基本工资4个字段内容。

(3)浏览或显示在1970年以前出生的所有女职工的记录内容。

4. 创建和使用索引。

(1)在“职工”表中,建立以下4个索引项(前2个为单项索引,后2个为多项索引):

职工号(主索引)、职称(普通索引)

职称与基本工资(普通索引)、部门与出生日期(普通索引)

(2)在“工资”表中,建立以下3个索引项:

职工号(主索引)、基本工资(普通索引,升序)、实发工资(普通索引、降序)

(3)分别按(1)、(2)中建立的索引项浏览表记录。

5. 对“职工”数据表进行以下属性设置:

(1)“职工号”字段的标题设置为“工作证编号”,有效性规则为:职工号的前2位必须为“10”且输入的职工号必须满6位。相应的提示信息为“职工号不符合要求”。

(2)“性别”字段的默认值设置为“男”。

6. 在“职工”表和“工资”表之间建立永久关系。