1、8.1 数据库的高级应用 8.2 设置表 8.3 建立表间关系 8.4 使用多个表,第八章 数据库和表的高级应用,8.1 数据库的高级应用 8.1.1 向数据库加入自由表用户可把不属于任何数据库的自由表添加入某个数据库中,一般有以下3种添加方法:(1) 在数据库设计器窗口中添加表:打开该数据库,从“数据库”菜单中选择“添加表”,在弹出的“打开”对话框中选择要添加的表,单击“确定”按钮即可。(2) 在项目管理器中添加表:打开项目管理器,选择“数据”选项卡,选中要添加表的数据库,单击“添加”,在弹出的“打开” 对话框中选中要添加的表,单击“确定” 按钮即可。(3) 使用ADD TABLE命令添加:
2、首先打开要添加表的数据库,再使用ADD TABLE 命令添加。,8.1.2 从数据库中移去表当数据库不再需要某个表或其它数据库需要添加此表时,可从该数据库中移去此表,使之成为自由表。与添加表相对应,它也有以下3种移走方法:(1) 在数据库设计窗口中移去表:打开该数据库,选中要移去的表,从“数据库”菜单中选择“移去”,在弹出的对话框中选择“移去”即可。(2) 从项目管理器中移去表:打开项目管理器,选中要移去的表,单击“移去”,在弹出的对话框中单击“移去”即可。(3) 使用REMOVE TABLE命令移去表:首先打开数据库,再使用REMOVE TABLE 命令将指定表移去。,8.1.3 使用其它数
3、据库中的表要使用一个非当前数据库中的表,可使用USE命令和“!”。命令格式:USE !其中,为将要打开的所在的数据库名。 例2假设现有一名为教学管理.DBC的数据库,其中有一个课程.DBF表文件,若当前数据库为雇员管理.DBC,要浏览课程.DBF表,可使用如下命令:OPEN DATABASE 雇员管理 & 打开雇员管理.DBCUSE 教学管理!课程 &打开非当前数据库中的表BROWSE,8.1.4 建立存储过程存储过程是保存在数据库中的独立程序,属于数据库管理的对象。使用存储过程主要是为了创建用户自定义函数,而这些函数是将会被字段级规则和记录级规则所引用的函数。当把一个用户自定义函数作为存储过
4、程保存在数据库中时,函数的代码保存在.dbc文件中,并且在移动数据库时,会自动随数据库移动,使用存储过程能使应用程序更容易管理,因为可以不必在数据库文件之外管理用户自定义函数。示例见P.173。,8.1.5 使用多个数据库在VFP中,有两种同时使用多个数据库的方法:一种是不打开数据库而引用其中的表;另一种是同时打开多个数据库,设置其中一个为当前数据库,并在其中选择表。1. 打开多个数据库根据需要,使用OPEN DATABASE命令打开多个数据库。2. 设置当前数据库在VFP中尽管可以同时打开多个数据库,但是只能有一个是当前数据库。所有对打开的数据库进行操作的命令和函数,如ADD TABLE命令
5、和DBC( )函数等,都是针对当前数据库而言的。设置当前数据库的命令格式:SET DATABASE TO 如果省略数据库名称,则没有设置当前数据库。,8.2 设 置 表,8.2.1 设置表在表设计器窗口,用户还可以对数据库表进行进一步的设置。1. 设置字段注释字段注释是对字段的说明信息,将和字段结构一同保存,但不显示出来。2. 设置字段的显示属性要为某字段设置显示属性,首先在“字段名”栏中选中该字段,再在“显示”组框内为该字段设置各项显示属性。,格式:用于确定一个字段在表单、浏览窗口或报表中的显示格式,它实际上是字段的输出掩码。下面是常用的格式码:D使用当前系统设置的日期格式。 L当输出数值型
6、数据时,用0代替前导空格。T禁止输入字段的前导空格和结尾空格字符。!把输入的小写字母转换为大写字母。$显示当前系统设置的货币符号。*在数值型数据的左侧显示“*”号。.用于指定数值型数据的小数点位置。,用于分隔小数点左边的整数部分,一般用来分隔千分位。,输入掩码:用于指定字段的输入格式,使用输入掩码可以屏蔽非法输入,减少人为的数据输入错误,保证输入的字段数据格式统一、有效,下面是常用的输入掩码。X可输入任何字符。9可输入数字和正负符号。A只允许输入字母(禁止输入数字、空格或标点符号)。# 可输入数字、空格和正负符号。Y只允许输入逻辑值Y,y,N,n,并把y和n分别变为Y、N。N只允许输入字母和数
7、字。 标题:通过为字段设置标题,可以定制表的浏览效果。,3.设置字段的有效性规则字段的有效性规则用来验证输入该字段的数据是否合法。 4.为字段设置默认值把字段最可能取的值设置为该字段的默认值,以简化输入。,8.3 建立表间关系,在一个数据库中,通常包含若干张表,如雇员管理.DBC数据库就包含了3张表:职工.DBF、工资.DBF、部门.DBF。它们之间并非彼此独立存在,而是相互联系的,关系数据库系统的一大特点就是可以建立表间的关系,以反映现实世界错综复杂的联系,减少数据的冗余。通常,表与表之间存在以下3种关系:一对一关系:一个表的一条记录对应另一个表的一条记录。一对多关系:一个表的一条记录对应另
8、一个表的多条记录。多对多关系:一个表的多条记录对应另一个表的多条记录。VFP只能直接处理前两种关系。,8.3.1 创建表间关系在数据库设计器中,通过连接不同的索引,可创建表与表之间的关系,这种关系将随着数据库的存在而一直存在,因此又称为永久关系。当在查询设计器、视图设计器或数据环境设计器中使用表时,这些永久关系将作为表间的默认链接出现。创建表间关系的步骤如下: 打开要创建表间关系的数据库,进入数据库设计器。 为各表中需建立关系的字段建立索引。如果两张表之间是一对一或一对多关系,则对父表(又称主表)的相应字段所建索引类型必须是主索引或候选索引,而对子表(又称从表)的相应字段所建索引类型可以是主索
9、引、候选索引、惟一索引或普通索引。若是主索引或候选索引,则表间关系是一对一的,否则,该关系为一对多。 创建表间关系。在数据库设计器中,用鼠标左键按住一个表的索引,将其拖放到想建立关系的另一个表的相应索引上即可。,8.3.2 删除表间关系 方法一:用鼠标单击对应的关系连线,此时,该关系连线变粗,按DEL键即可; 方法二:右击鼠标,从快捷菜单中选择“删除关系” 。,8.3.3 编辑表间关系 方法一:用鼠标单击相应的关系连线,使其变粗,再右击鼠标,从弹出菜单中选择“编辑关系” ; 方法二:用鼠标双击相应的关系连线,打开“编辑关系”对话框。,8.3.4 编辑参照完整性参照完整性涉及主关键字和外部关键字
10、的概念,首先看一下什么是主关键字和外部关键字。(1) 主关键字:表中的某个字段(或最小字段组合)可以唯一地确定一条记录,称为该表的主关键字。例如,职工表中的职工号,可以唯一地确定一个职工,即职工号为职工表的主关键字。假设“雇员管理”数据库中另有一个“部门表”,由“部门名”、“部门电话”、“负责人”字段组成,我们可以将表的结构写成如下的形式:部门(部门名,部门电话,负责人)在该表中,部门名可以唯一确定一个部门记录,即部门名为该表的主关键字。,在职工表和部门表中,有一对相同性质的字段:职工表中的“部门”字段和部门表中的“部门名”字段。它们都是表示部门名称的,并且通过这对字段可以把职工和部门联系起来
11、。(2) 外部关键字(也称为外关键字):设有表1和表2两个数据库表,如果表1中有一个字段(或字段组合)A,A不是表1的主关键字,但和表2的主关键字相对应,则称A是表1的外部关键字。例如,上述职工表和部门表中,字段“部门”不是职工表的主关键字,但又和部门表中的主关键字“部门名”相对应,所以字段“部门”是职工表的外部关键字。,为了使数据库中的数据保持一致性,一般应遵循参照完整性规则:设有两张表(表1和表2),设表2有一字段(或字段组合)A,其中A与表1的主关键字相对应,又是表2的外部关键字,则对于表2中A的取值只有两种可能性: 取空值。 等于表1中某个记录的主关键字值。参照完整性是控制数据的一致性
12、,遵照不同表的主关键字和外部关键字之间关系的规则,使得在表中插入、删除、更新记录时,能保持已定义的表间关系。参照完整性可在“参照完整性生成器”对话框中进行设置。,进入该生成器的步骤是: 从“数据库”菜单中选择“清理数据库”命令。 选择以下3种方法之一即可进入“参照完整性生成器”对话框: 方法一:在“数据库设计器”中用鼠标双击两个表之间的关系连线,在弹出的“编辑关系”对话框中单击“参照完整性”。 方法二:在“数据库设计器”中右击鼠标,从弹出的快捷菜单中选择“编辑参照完整性”。 方法三:选择“数据库”菜单的“编辑参照完整性”。, 在“参照完整性生成器”对话框中,用户可以设置更新、删除或插入父表与子
13、表记录时应遵循的规则。“插入规则”选项卡:用于设置在子表中插入新的记录,或者更新一个已存在的记录时所用的规则。“更新规则”选项卡:用于设置当修改父表中的关键字值时所用的规则。“删除规则”选项卡:用于设置在删除父表中的记录时所用的规则。对于更新和删除规则,有3种选择:“级联”、“限制”和“忽略”;而对于插入规则,则只有“限制”和“忽略”两种,下面分别进行介绍:,限制:当子表中有相关记录时,禁止更新或删除父表中的主关键字段或候选关键字段中的值。对于“插入规则”,若选择此项,则当在子表中插入记录时,若父表中存在相匹配的关键字值时,则将禁止该插入操作。忽略:忽略父表与子表的关系,不限制父表中关键字段的
14、更新。在生成器中完成参照完整性的设置后,单击“确定”,并在弹出的对话框中选择“是”,则系统将生成参照完整性代码,并把这些代码与已经存储在数据库存储过程中的代码合并存储在数据库的存储过程中,即保存在.DBC文件中,原存储过程中的代码备份在risp.old文件中。最后退出生成器而返回到数据库设计器。示例见P.180。,8.4 使 用 多 个 表,在一个应用系统的数据库中,往往有多个表文件,有时可能需要同时打开几个表文件进行操作,通常称这种操作为多表文件操作。,8.4.1 同时打开多个表文件 1工作区和当前工作区工作区是VFP在内存中提供的一块区域。在一个工作区中,可打开一个表文件及有关其它文件,如
15、备注文件、索引文件等,并且每一个工作区都拥有自己独立的记录指针。在VFP中,最多可有32767个工作区。,虽然每一个工作区中都可存在一个打开的表文件,但是,在任何时刻,用户只能对一个工作区中的表文件进行操作,这个工作区称为当前工作区。在当前工作区中打开的表文件称为当前打开表文件,简称当前表文件。在非当前工作区中打开的表文件为非当前打开表文件,简称非当前表文件。对当前表文件进行操作时,可以引用非当前表文件的内容,但不影响非当前表文件的任何数据。除非特别声明,一般也不影响非当前表文件记录指针的指向。用户可以选择任一工作区为当前工作区。,2. 选择当前工作区每个工作区都有自己的标号和别名。用户利用工
16、作区的标号和别名来选择、更改当前工作区。(1) 工作区的标号:VFP为每个工作区赋予一个惟一的标号,分别为1,2,3,32767,也称为工作区的区号。对应地,这些工作区也分别称为:1号工作区,2号工作区,32767号工作区。启动VFP后,系统自动选择1号工作区为当前工作区。,(2) 工作区的别名:除了标号,系统为每个工作区规定了一个固定别名,称为系统别名。用户也可为工作区定义一个别名,称为用户别名。 工作区的系统别名:110号工作区的系统别名分别为A、B、J;1132767号工作区的系统别名分别为W11 W32767 。 工作区的用户别名。用户在某工作区中打开一个表文件的同时可以为工作区定义了
17、一个别名,称用户别名。, 定义用户别名的USE命令。命令格式如下:USE ALIAS NOUPDATE 有ALIAS选择项时,就是用户为当前工作区规定的用户别名;无ALIAS选项时,打开的表文件名就是当前工作区的用户别名。 是用英文字母或下划线开头,由英文字母、数字、下划线组成,最长为254个字节的字符串。AJ不能作为用户别名。 当有NOUPDATE项时,不允许修改打开表文件的结构。当一个工作区没有打开表文件时,它只有系统别名,否则,它有系统和用户两种别名。,(3) 选择当前工作区命令SELECT命令:刚进入VFP时,1号工作区是当前工作区,SELECT命令可改变当前工作区。 命令格式:SEL
18、ECT / 执行后,命令中规定的工作区即为新的当前工作区。在上述命令中,选用的工作区号、该工作区的系统别名、用户别名(若存在)都是等价的。例如,SELECT 2和SELECT B两个命令选择的是同一工作。SELECT命令对任何工作区中已打开表文件的内容及记录指针的指向都不产生任何影响。例如,下面一个程序: SELECT 1 USE 工资 ALIAS SALARYUSE 职工 GO 6GO 5 SELECT 职工SELECT B,当前工作区是十分重要的工作区。在编制应用程序时,软件人员必须清楚当时的当前工作区号,否则,就会引起错误。例如,在上例中,用户若想继续对“工资.DBF”表文件进行操作,就
19、必须先再次执行一条SELECT命令,使2号工作区成为当前工作区。,3. 浏览工作区若希望了解系统中工作区的应用情况,在VFP中有两种方法: 从“窗口”菜单中选择“数据工作期”选项; 在命令窗口使用SET命令。,8.4.2 调用非当前表文件数据联访VFP提供了调用非当前表文件数据的方法联访。下面介绍两种联访格式:格式1: .格式2: - 例如,B-基本工资、B .房电费。用来指定要访问的工作区,为该工作区中打开表文件的一个字段名,所得到的值是该工作区中打开表文件的当前记录的此字段值。由于联访只能调用非当前表文件中当前记录的字段值,因此,为取得正确数据,在联访前,必须在被访工作区中,使被引用数据的
20、记录成为当前记录,然后才能进行联访。示例见P.183。,8.4.3 被访工作区记录指针的自动移动关联(临时关系)在建立表间的关联即临时关系后,就会使得一个表(子表)的记录指针自动随另一个表(父表)的记录指针移动。这样,便允许当在关系中的父表选择一个记录时,会自动去访问表关系中子表的相关记录。 1. 实现关联命令SET RELATION 命令格式: SET RELATION TO INTO /ADDITIVE 命令功能:使工作区中的表文件与当前表文件建立关联。当前表文件为主动表文件,也称父表文件,被关联表文件称为子表文件。,通常建立关联的两个表具有相同字段,而且用来建立关系的表达式常常就是子表主
21、控索引的索引表达式。 每当父表文件记录指针移动到某记录时,子表文件的记录指针指向其主控索引中与相匹配的第一条记录。若找不到匹配记录,则指针指向子表文件尾后,EOF( )为 .T.。 若子表没有指定主控索引,则命令中的必须是数值型的。当父表文件记录指针移动时,子表记录指针指向记录号等于值的记录。若无此号记录,则指针指向尾后,EOF( )为 .T.。 若未选用ADDITIVE选择项,命令将取消当前表原有的关联;若选用了此选择项,则保留当前工作区原有的关联。即,当前表可同时与多个非当前工作区中的表建立关联。,2. 取消关联 有3种方法可以取消当前表与非当前工作区中的表之间的关联。 (1) 在建立新关
22、联时,不选用ADDITIVE选择项,将取消当前表与非当前工作区中表之间原有的关联。 (2) 使用 SET RELATION TO 命令,将取消当前表与所有非当前工作区中表之间的所有关联。 (3) 使用命令SET RELATION OFF INTO /,取消当前表与命令中指定表之间的关联,其余关联仍保留。,总结永久关系和临时关系,索引用于在数据库中建立表间的永久关系。永久关系是存储在数据库文件中的关系,并在查询设计器和视图设计器中,自动作为默认连接条件使用的数据库表间关系。永久关系在数据库设计器中显示为表索引间的连接线,当在该数据环境中打开这些表时,永久关系也作为默认关系显示。与SET RELA
23、TION命令设置的临时关系不同,永久关系在每次使用表时不需要重新创建。但是,由于永久关系并不控制表中记录指针间的关系,因此在开发 Visual FoxPro 应用程序时,不仅需用永久关系,也需使用SET RELATION创建的临时关系。,8.4.6 多表文件函数为了方便用户,VFP提供了丰富的多表文件函数,下面分别进行介绍。1ALIAS( )别名函数格式:ALIAS(/)功能:给出指定工作区的用户别名。若指定工作区中无打开的表文件,则返回一个空串。:数值型,给出指定工作区的工作区号。:字符型,给出指定工作区的别名。,例10 OPEN DATABASE 雇员管理SELECT 1USE 职工 AL
24、IAS ZGSELECT 2USE 工资?ALIAS( “A“) &结果为ZG,2BOF( )文件起始函数格式:BOF(/) 功能:判定在指定工作区中记录指针在反向移动时,是否已到达文件头。若到达文件头,函数值为 .T.,否则,函数值为.F.。若指定工作区中无打开的表文件,函数值也为 .F.。 3EOF( )文件结束函数格式:EOF(/)功能:判定在指定工作区中记录指针在正向移动时,是否已超过最末一个记录。若超过,函数值为 .T.,否则,函数值为 .F.。若指定工作区中无打开的表文件,函数值也为.F.。,4DBF( )表文件名函数格式:DBF(/) 功能:给出在指定工作区中打开的表文件名(若不
25、存在,则返回一个空串)。 5CDX( )复合索引名函数格式:CDX( ,/)功能:给出在指定工作区中,序号为的复合索引文件名。注:.IDX文件忽略不计。若有结构复合索引文件存在,它的序号为1。,6FCOUNT( )字段数函数格式:FCOUNT(/) 功能:给出在指定工作区中打开的表文件的字段数。若指定工作区中无打开的表文件,则函数值为0。 7FIELD( )字段名函数格式:FIELD( ,/)功能:给出在指定工作区中由规定字段序号的字段名。若指定工作区中无打开的表文件,或值超过字段个数,则函数返回空串。,8. DELETED()删除标记函数格式:DELETED(/)功能:若指定工作区当前记录有
26、删除标记,则函数值为.T.,否则函数值为.F.。 10FOUND( )查找成功函数格式:FOUND(/)功能:在指定工作区中最近一次数据搜索若成功,函数值为 .T.,否则函数值为 .F.。数据搜索命令为FIND、SEEK、LOCATE和CONTINUE。注意:即使最近一次搜索成功,但记录指针又被其它命令移动,函数值仍为 .F.。,例11OPEN DATABASE 雇员管理USE 职工OCATE FOR 职称=“工程师“ & 3#记录?FOUND( ) & 得.T.GO 3 ?FOUND( ) & 得.F.,11FSIZE( )字段宽度函数格式:FSIZE( ,/)功能:给出在指定工作区中以值为
27、名的字段的宽度。 12KEY( )索引关键字表达式函数格式:KEY(, ,/)功能:返回在指定工作区的中,第个标识的索引关键字表达式。若未指定,则返回所有打开的索引文件中第个索引(或标识)的索引关键字表达式。,13UPDATE( )修改日期函数格式:UPDATE(/ )功能:给出在指定工作区中打开表文件最近一修改日期(日期型)。若指定工作区中无打开表文件,则返回一个空日期。 14MDX( )复合索引名函数格式:MDX( ,/)功能:给出在指定工作区中序号为的复合索引名。,16ORDER( )主控索引名函数格式:ORDER (/,)功能:返回指定工作区中的主控索引名。可取任意值。若有该项,则返回
28、的是带有盘号和路径的主控索引文件名。,17RECCOUNT( )记录个数函数格式:RECCOUNT(/ )功能:给出在指定工作区中打开表文件的记录个数(若不存在,返回0)。 18RECNO( )当前记录号函数格式:RECNO(/ )功能:给出在指定工作区中当前记录的记录号。 19RECSIZE( )记录长度函数格式:RECSIZE(/ )功能:给出在指定工作区中打开表文件的记录长度。,20RELATION( )关联表达式函数格式:RELATION ( ,/)功能:返回在指定工作区中第个关联的关联表达式(字符型)。若指定工作区无打开表文件,或无关联,则返回空串。 21SELECT( )工作区号函
29、数格式:SELECT(0/1)功能:返回工作区号。SELECT(0)返回当前工作区号;SELECT(1)返回当前未被使用的、序号最大的工作区号。SELECT( )与SET COMPATIBE命令的设置有关:COMPATIBE为OFF时,SELECT( )等价于SELECT(0);COMPATIBE为ON时,SELECT( )等价于SELECT(1)。,22SYS(7)格式文件名函数格式:SYS(7,)功能:返回在指定工作区中打开格式文件的文件名。若无打开格式文件,则返回空串。23SYS(14)索引表达式函数格式:SYS(14, ,/)功能:返回在指定工作区中第个索引的索引表达式。,24TAG(
30、 )索引名函数格式:TAG(, ,/)功能:给出在指定工作区的 中,第个标识的标识名。25TARGET( )关联工作区别名函数 格式:TARGET( ,/)功能:返回在指定工作区中建立的第个关联的工作区的别名。若在指定工作区中无第个关联,则返回空串。,26USED( )已使用函数格式:USED(/)功能:若在指定工作区中有打开表文件,则返回.T.,否则,返回.F.。,8.4.7 其它多表文件命令 1SET ORDER命令 格式:SET ORDER TO /TAGIN/ASCENDING/DESCENDING 功能:在指定工作区中指定第个索引或某为主控索引。该命令既可规定按升序索引(选择ASCE
31、NDING),也可规定按降序索引(选择DESCENDING),或以该索引原有顺序索引(两者都不选)。,2SET SKIP命令格式:SET SKIP TO,功能:在工作区之间建立一对多的关系。前面介绍过,SET RELATION命令使两个工作区中打开的表文件发生关联:父表文件记录指针移动时,子表文件记录指针也将根据关联表达式(也是子表文件的主控索引)指向与之匹配的第一条记录(若找不到匹配记录,指针指向子表文件尾后,并使EOF( )为.T.)。,但是,当子表文件有多条记录与父表文件当前记录相匹配时,能否使用子表文件中所有与之匹配的记录呢?SET SKIP命令能做到这一点。首先,本命令必须在SET
32、RELATION命令后使用,即首先用SET RELATION命令建立一个对应的关联,然后使用SET SKIP命令,在已有父子表文件关联的基础上,建立一对多关联。TO, 表示若一个表文件已有多个表文件与之关联(一一对应关联),则这些关联表文件的别名都可进入本命令。这就在一个父表文件和多个子表文件之间建立了一对多关联。,当一个父表文件和一个(或多个)子表文件建立了一对多关联后,当在父表文件中移动指针时,一开始,移动的并不是父表文件中的记录指针,而是使子表文件的记录指针在所有与父表文件相匹配记录间移动,直至子表文件记录指针移过所有相匹配记录后,父表文件记录指针才移向下一个记录。无任选项的本命令,SET SKIP TO将解除一对多关联,但一一对应关联仍然存在。一一对应关联可用无任选项的SET RELATION TO命令解除。,