表文件中记录的顺序通常是人们在输入数据时按输入的先后次序存储的,并以记录号表示,这个顺序只反映了存放数据的先后顺序。但在数据处理实际应用中,由于数据库十分庞大,为了高效方便地处理数据,常常需要对记录位置进行重新整理,并按某种指定的顺序对表记录进行处理。例如,对学生成绩表按学号为序显示输出记录,以便查找;或按总分高低为序输出记录,以便进行比较等等。
对记录位置进行重新整理通常有排序和索引两种方法。排序是对表文件进行物理位置的整理;索引是对表文件进行逻辑位置的整理。
表文件的排序操作就是根据表的某个关键字或关键字表达式重新排列表记录的位置。执行排序操作后将生成一个新的表文件(称为:排序文件)。新文件的结构和数据可以与源文件完全相同,也可以只取源文件的部分字段。新文件不改变源文件内容和记录顺序。
【命令】 SORT TO<新文件名>ON <字段名1>[/A] [/D] [/C] [,<字段名2> [/A] [/D] [/C]…] [ASCENDING|DESCENDING][<范围>][FOR<条件>|WHILE<条件>][FIELDS<字段名表>| FIELDS LIKE<通配符>|FIELDS EXCEPT<通配符>]
【功能】 对当前表中指定范围内、满足条件的记录按指定字段升序或降序重新排序,并将排序结果存入新文件名中。
【说明】
①排序结果存入由TO <新文件名>指定的表文件中,系统默认文件扩展名为.DBF。
②在ON子句中的字段名表示排序的关键字段。当使用一个关键字时,叫“单重排序”;使用多个关键字时,叫“多重排序”。在多重排序中,关键字有主次之分。主关键字是指能够唯一标识某个记录的关键字;次关键字是指标识具有某种相同属性的某些记录的关键字。在关键字表达式中,主关键字排在前面,次关键字排在后面。执行排序操作时,先按主关键字排列,当在主关键字出现相同字段值时,再按次关键字排序。
③关键字段可以是N型、C型或D型,但不能是L型、M型和G型数据。即不可选用备注型或通用型字段来排序。其中:N型以数值大者为大;C型以拼音顺序A~Z;D型以后面的日期为大。
④参数/A或ASCENDING表示升序排序;/D或DESCENDING表示降序排序。省略时,表示升序;/C只适用于C型数据,选择/C时,不区分大小写字母,省略/C时,小写字母大于大写字母。
⑤省略<范围>、FOR<条件>/WHILE<条件>等子句,则对所有记录排序。
⑥FIELDS子句指新表中包含的字段,省略时,默认新表包含源表中所有字段。<字段名表>可以包含其他工作区中的表文件字段,但必须使用别名调用格式:
工作区号->字段名;或:别名->字段名;或:别名.字段名。
【例5-1】 对表文件“学生.DBF”中的男生按入校总分降序排序,生成新文件“入校总分.DBF”,且新表中只包含学号、姓名、入校总分3个字段。
USE学生
BROWSE && 显示结果如图5-1所示。
图5-1 学生.DBF显示结果
SORT TO 入校总分 ON 入校总分/D FIELDS 学号,姓名,入校总分
USE入校总分
BROWSE && 显示结果如图5-2所示。
图5-2 入校总分.DBF显示结果
【例5-2】 对“教师.DBF”记录中享受政府津贴的教师按姓名升序排序,生成新文件“政府津贴.DBF”。
USE 教师
BROWSE && 显示结果如图5-3所示。
图5-3 教师.DBF显示结果
SORTTO 政府津贴 ON 姓名FOR 政府津贴
USE政府津贴
BROWSE && 显示结果如图5-4所示。
图5-4 政府津贴.DBF显示结果
Visual FoxPro的索引文件由指向.DBF文件记录的指针构成,这些指针指向表文件中的记录,在逻辑上按照指定索引关键字排序,索引并不改变表记录的物理顺序,只是与表记录建立一种逻辑关系。
索引和表(.DBF)分别存储在两个文件中。在索引文件中,只包含索引关键字和记录号两个字段,每个关键字值对应表文件中的一个记录号,利用记录指针的移动确定记录的逻辑顺序。索引是一种不可显示文件。
如果用户希望按照某种特定顺序查看和访问表记录,例如按总分从高到低的顺序查看学生表中的记录,可以按总分索引,然后根据这个索引关键字设置表中记录的顺序,并且按新的顺序访问表记录。使用索引可以加速对表的查看和访问操作,这类似于一本书按目录快速查找内容。
1. 物理顺序、逻辑顺序与使用顺序
记录储存在表文件中的实际排列顺序,称为物理顺序。执行排序操作后,记录在排序文件中形成的顺序就是一种物理顺序。
按照某个关键字或关键字表达式在关键字与记录号之间建立的一种逻辑上的顺序,称为逻辑顺序。执行索引操作后,索引关键字与记录号建立的顺序就是一种逻辑顺序。
实际操作的记录顺序,称为使用顺序。使用顺序可以是物理顺序,也可以是逻辑顺序。记录指针在表记录中的移动是按使用顺序进行的。
2. 索引的分类
Visual FoxPro的索引分为单索引和复合索引。
只包含一个索引项的索引文件,称为单索引文件(又叫独立索引文件)。单索引文件扩展名为.IDX。
包含有多个索引项的索引文件,称为复合索引文件。在复合索引文件中每个索引项都有一个索引标识(Index Tag),代表索引的名称。复合索引文件自动被压缩,以压缩方式储存,占有较小空间。复合索引文件在使用时必须打开,而且在更新表文件数据时,必须使其处于活动状态。复合索引文件扩展名为.CDX。
根据功能不同,复合索引可以分为主索引、候选索引、普通索引和唯一索引4种类型。
(1)主索引
主索引是设定有主关键字的索引,主关键字能唯一确定记录的顺序,它不允许在指定字段中出现重复值。如果在任何已经包含了重复数据的字段中指定主索引,Visual FoxPro 将返回一个错误信息。例如,将姓名字段作为主索引关键字,若出现同名同姓人员,也即出现了关键字重复值,这样的关键字就不是主关键字。主索引仅适用于表表,一个数据表只能创建一个主索引,自由表不能创建主索引。
(2)候选索引
像主索引一样候选索引要求字段值的唯一性,它不包含 NULL值或重复值。如果在任何包括重复数据的字段中指定候选索引,Visual FoxPro 将返回一个错误信息。一个数据表或自由表中都可以建立多个候选索引。
(3)普通索引
普通索引不要求字段值具有唯一性,可以决定记录的处理顺序,且允许字段中出现重复值。一个数据表或自由表中可以有多个普通索引。
(4)唯一索引
不允许两个记录具有相同的字段值,对于关键字值相同的记录,索引中只列入其中的第一个记录。一个数据表或自由表中可以有多个普通索引。
复合索引文件分为有结构的结构复合索引文件和无非结构的独立复合索引文件。结构复合索引文件的由Visual FoxPro自动命名,与表文件同名,它随表文件的打开而打开,在对表增加或删除记录时系统会自动维护。独立复合索引文件与表文件不同名,且不随表文件的打开而打开。打开独立复合索引文件要使用SET INDEX命令。
3. 永久关系与参照完整性
主索引用于表表中主表或“被引用”表,在一个永久关系中建立参照完整性。
(1)永久关系
指表中表之间的一种保存在数据表文件中的关系。在表设计器中可以看到连接两个表索引之间的关系线。
(2)参照完整性
在永久关系的相关表中,如果只对其中的一个表进行插入、更新或删除操作,就会影响到数据的完整性。因此,参照完整性属于表表间规则,用于控制数据的一致性。为了保持参照完整性,可以利用“参照完整性生成器”建立规则,控制记录在相关表中的插入、更新或删除。
1. 命令方式
【命令】 INDEX ON <索引关键字|索引关键字表达式> TO <单索引文件名> |TAG<索引标识名> [OF <复合索引文件名> ][FOR<条件>] [COMPACT] [ASCENDING |DESCENDING] [UNIQUE | CANDIDATE] [ADDITIVE]
【功能】 对当前表文件按指定关键字建立索引或增加索引标识。
【说明】
①<索引关键字|索引关键字表达式> :指定建立索引文件的关键字。可以是一个字段,也可以是多个字段组成的关键字表达式,多个字段之间用“十”或“一”连接,主关键字在最前面,且数据类型要相同。<索引关键字>可以是N型、C型、D型。
②TO 子句建立单索引(.IDX)。TAG子句建立复合索引(.CDX)及索引标识。选项COMPACT 指定单索引为压缩文件。
③OF子句指定独立复合索引文件名。缺省该子句表示建立结构复合索引文件。
④FOR<条件> 对符合条件的记录建立索引,缺省该条件则对所有记录建立索引。
⑤ASCENDING表示升序索引;DESCENDING表示降序索引;UNIQUE表示建立唯一索引;TAG CANDIDATE表示候选索引。
⑥ADDITIVE表示建立索引文件时,并不关闭先前的索引。
⑦索引文件不能单独使用,必须同表文件一起使用。
⑧该命令默认建立普通索引型索引文件。
【例5-3】对学生.DBF按入校总分建立单索引文件。
USE 学生
INDEX ON 入校总分 TO ZF
LIST
【例5-4】学生.DBF建立复合索引,其中包含3个索引:
(1)以姓名降序排列,索引标识为普通索引。
USE 学生
INDEX ON 姓名 TAG xm DESCENDING
**建立复合索引文件学生.CDX,xm为普通索引标识
LIST
(2)以性别升序排列,性别相同时以入校总分升序排列,索引标识为普通索引。
INDEX ON 性别+STR(入校总分,3) TAGxbzfa
**关键字为性别+STR(入校总分,3),普通索引标识xbzfa加入学生.CDX中
LIST
(3)以性别升序排列,性别相同时以出生年月降序排列,索引标识为候选索引。
INDEX ON 性别-DTOC(出生年月) TAG xbcsd CANDIDATE
** xbcsd为候选索引型索引标识,索引标识xbcsd加入学生.CDX
LIST
2. 菜单方式建立索引
【菜单】 单击“文件”菜单→单击“打开”命令→选中“表”选项→“显示”菜单→表设计器→“索引”选项卡→“索引名”→“排序”→“类型”→“表达式”→单击“确定”按钮。如图5-5所示。
图5-5 表设计器中”索引”选项卡
【例5-5】 利用表设计器建立或修改索引。
(1)选择“文件”菜单中的“打开”命令,选择表文件“学生.DBF”。
(2)选择“显示”菜单中的表设计器,单击“索引”选项卡,将“索引名”设为XBXHAD,单击该表达式右侧的按钮,弹出“表达式生成器”对话框,如图5-6所示。在“字段”列表框中双击“性别”,在“数学”组合框中选定“+”号,在“字段”列表框中双击“学号”,这时,“表达式”列表框中显示“性别+学号”。也可以在“表达式”列表框中直接输入表达式“性别+学号”。
图5-6 表达式生成器
(3)单击“确定”按钮,便完成建立工作。
(4)利用“表设计器”对话框中的“插入”按钮在当前行前插入一个空行,可以建立新索引。利用“删除”按钮可以删除选定的索引。
使用索引查询必须满足以下条件:
(1)打开表。
(2)打开索引文件。
(3)确定主控索引文件。
(4)对于复合索引文件还需确定主控索引。
1. 打开索引文件
使用索引,必须同时打开表文件和索引文件。打开索引文件就是把索引文件调入内存,并对当前相关表进行排序。打开一个表文件时,结构化复合索引文件将随着表文件的打开而打开,如果要使用其他索引文件,则要使用命令来打开索引文件。
一个表文件可以打开多个索引文件,但任何时刻只有一个索引文件起作用,当前起作用的索引文件称为主控索引文件。只有主索引文件对表文件才有控制作用,记录指针总是指向主索引文件关键字值的第一个记录上。同一个复合索引文件可能包含多个索引标识,但任何时刻只有一个索引标识起作用,当前起作用的索引标识称为主控索引。
打开索引文件有3种方法:
(1)在建立索引文件的同时,就打开了索引文件。
(2)打开表文件的同时打开索引文件
【命令】 USE <表文件名>|?[INDEX <索引文件名表>|?][ORDER [<数值表达式>]|<单索引文件名>|[TAG]<标识名>[OF <复合索引文件名>] [ASCENDING |DESCENDING]]]
【功能】 打开表文件的同时打开一个或多个索引文件。
【说明】
①INDEX <索引文件表>包括单索引或复合索引文件,其中第一个索引文件是主索引。
②选择“?”将弹出多个表文件或索引文件,供选择。
③ORDER [<数值表达式>]是将<索引文件名表>中的第几个设置为主控索引。
④ORDER [<单索引文件名>]指定<单索引文件名>为主控索引文件。
⑤ORDER [TAG]<标识名>[OF <复合索引文件名> ] 指定复合索引的<标识名>为主控索引;不选择[OF <复合索引文件名> ],则打开结构复合索引文件。
【例5-6】应用举例。
USE 学生 INDEX 学生 ORDER TAG xbxha
USE 学生 INDEX 学生 ORDER TAG xm
(3)打开表文件后再打开索引文件
【命令】 SET INDEX TO<索引文件名表> [ADDITIVE]
例如:
USE 学生
SET INDEX TO zf
2. 设置主控索引
如果只打开一个索引文件,它自然就是主控索引文件;如果打开了多个索引文件,可以利用设置主索引文件命令来改变主索引文件。
【命令】 SET ORDER TO[<数值表达式>|<单索引文件名>|[TAG]<索引标识名>[OF <复合索引文件名> ] [ASCENDING|DESCENDING]]
【功能】 对打开的索引文件中指定主控索引文件,或在打开的复合索引文件中设置主控索引。
【说明】 SET ORDER TO 0 或SET ORDER TO 都是取消主控索引文件或主控索引。
【例5-7】 为如图5-7所示的复合索引文件学生.CDX设置主索引。
图5-7 复合索引文件学生.CDX
USE学生
SETORDER TO 2 && 指定学生.CDX中的索引序号2(即xm)为主控索引。
SETORDER TO xbxha &&指定学生.CDX中的索引标识xbxha为主控索引。
SETORDER TO zf &&指定单索引文件zf.IND为主控索引文件。
3. 更新索引
当对表文件进行追加、修改等操作后,对于打开的索引文件或随着表文件打开而打开的复合索引文件,系统自动将其更新,而对于那些没有打开的索引文件则变得无意义了。为了使这些索引文件仍然有效,可以利用重新索引命令,使其与修改后表文件保持一致。
【命令】REINDEX [COMPACT]
【功能】重新建立打开的索引文件。
【说明】
(1)在更新索引之前,应打开表文件和相应的索引文件。
(2)选择COMPACT,将非压缩单索引文件转换为压缩单索引文件。
【例5-8】更新索引举例。
USE 学生
LIST && 显示有10条记录
APPEND && 追加一条记录
USE
USE 学生 INDEX 学生 ORDER TAG xm &&打开主关键字为姓名的复合索引文件
LIST && 显示有11条记录被索引
USE 学生
SET INDEX TO ZF && 打开主关键字为入学总分的单索引文件
LIST && 显示只有10条记录被索引
REINDEX
LIST && 显示有11条记录被索引
4. 关闭索引文件
关闭索引文件,就是取消索引文件对表文件的控制作用。
关闭索引文件有三种方法:
(1)关闭当前索引文件:SET INDEX TO
(2)关闭所有索引文件:CLOSE INDEX
(3)关闭表文件的同时,关闭索引文件:USE
5. 删除索引
可以通过删除复合索引文件中的索引标识来删除不再使用的索引,或者通过删除单索引 文件本身来删除独立索引。删除无用的索引标识可以提高数据处理性能,因为 Visual FoxPro 不必再去更新无用标识来反映表中数据的变化。
由于复合索引中包含由多个索引标识,所以应采用删除索引标识的方法。
【命令】 DELETE TAG ALL|<索引标识1>[,<索引标识2>]……
【菜单】 “文件”菜单→“打开”命令→“表”选项→“显示”菜单→表设计器→“索引”选项卡→“索引名”→“删除”。
【功能】 从指定复合索引文件中删除指定索引标识,或删除所有索引标识。
【说明】 当删除指定复合索引文件中的全部标识后,该复合索引文件将自动被删除。
查询就是按指定的查询条件查找符合条件的记录。排序和索引的主要目的也是为了对表文件快速查询。
Visual FoxPro提供了几个与索引相关的函数FOUND()、RECNO()和三个检索命令LOCATE与CONTINUE、SEEK|FIND、SQL语言的查询命令:SELECT-SQL。
1. 记录找到否测试函数
【命令】 FOUND([<工作区号>])
【功能】 判断记录是否找到。
【说明】 如果记录找到,则函数返回值为.T.;否则函数返回值为.F.。如果指定工作区中的表文件没有打开,则函数返回值为假。
2. 求得记录号函数
【命令】 RECNO(0)
【功能】 给出当前正在使用的表文件的当前记录号。
【说明】 若指定工作区中的表文件没有打开,则函数返回值为0。
顺序查询又叫直接查询,是按照表记录的物理位置依次逐个查询。
1. 顺序查询命令
(1)LOCATE命令
【命令】 LOCATE[范围][FOR<条件>]|[WHILE<条件>]
【功能】 从指定范围内查找满足条件的第一个记录,并将记录指针定位在此。
【说明】 省略[范围]和[FOR<条件>]|[WHILE<条件>],系统默认为ALL。该命令一旦找到符合条件的第一个记录,记录指针立即指向该记录,并且停止继续查找,显示其记录号,但不显示记录内容;如果没有找到,记录指针则定位在范围末尾,屏幕显示“已到定位在范围末尾”。
2. CONTINUE命令
【命令】 CONTINUE
【功能】 与LOCATE命令连用,继续查找LOCATE命令指定条件的记录。
【说明】 CONTINUE命令必须用在LOCATE命令之后。每执行一次CONTINUE命令,将继续查找下一个符合条件的记录。
【例5-9】 在“学生.DBF”中查找姓名为王小平的记录。
USE学生
LOCATEALL FOR 姓名=“王小平”
DISP
CONTINUE && 屏幕显示:已到定位在范围末尾。
【例5-10】 在“教师.DBF”中查找职称是教授的记录。
USE教师
LOCATE ALLFOR 职称=“教授”
DISP
CONTINUE
DISP
CONTINUE && 屏幕显示:已到定位在范围末尾。
索引查询又叫快速查询,是按照表记录的逻辑位置查询。因此,索引查询要求被查询表文件建立并打开索引。
1. FIND命令
【命令】 FIND <字符型常量>|<数值型常量>
【功能】 在打开的索引文件中查找索引关键字与<字符型常量>或<数值型常量>相匹配的第一个记录,并将记录指针定位在此。
【说明】
①FIND命令只能对已建立并打开的索引文件进行查询。如果查找成功,记录指针定位在符合条件的第一个记录上,并停止继续查找,FOUND()函数值为.T.;否则,屏幕显示:“没有找到。”,FOUND()函数值为.F.,EOF()函数值为.T.。
②FIND命令可以使用内存变量,如果是C型内存变量,必须宏代换:FIND &<C型内存变量>;如果是N型内存变量,则先用STR()函数将其转换为C型内存变量后,再用宏代换。
③FIND命令只查找符合条件的第一个记录,与SKIP命令配套使用可以实现继续查找。
④利用SET EXACT ON 命令可以实现对C型数据进行精确查找,即要求C型数据精确匹配;利用SET EXACT OFF命令可以可以实现对C型数据进行模糊查找,即不要求C型数据精确匹配。
【例5-11】 在学生DBF中查找姓名为王小平的记录。
USE学生
INDEXON 姓名TAG xm
FIND王小平
DISP
【例5-12】 在学生DBF中查找男同学的记录。
USE学生
INDEXON 性别TAG xb
FIND男
LISTFOR 性别=“男”
【例5-13】 使用内存变量示例。
tn=STR(595)
INDEXON 入校总分 TAG rxzf
FIND&tn
DISPFIELDS 姓名,入校总分
tm=“张 强”
INDEXON 姓名 TAG xm
FIND&tm
DISPFIELDS 姓名
2. SEEK命令
SEEK命令比FIND命令的功能更强。它不仅能够查找C型和N型数据,还能够查找D型和L型数据。
【命令】 SEEK<表达式>[ORDER <索引号>|<单索引文件名>]|[TAG]<索引标识>
【功能】 在打开的索引文件中查找主索引关键字与<表达式>相匹配的第一个记录,并将记录指针定位在此。
【说明】
①SEEK命令只能对已建立并打开的索引文件的表文件进行检索。如果查找成功,记录指针定位在符合条件的第一个记录上,并停止继续查找,FOUND()函数值为.T.;否则,屏幕显示:“没有找到。”,FOUND()函数值为.F.,EOF()函数值为.T.。
②SEEK命令可以查找C型、N型、D型、L型数据。如果查找C型常量,必须用定界符将C型常量引起来。
③SEEK命令只查找符合条件的第一个记录,与SKIP命令配套使用可实现继续查找。
④利用SET EXACT ON 命令可以实现对C型数据进行精确查找,即要求C型数据精确匹配;利用SET EXACT OFF命令可以可以实现对C型数据进行模糊查找,即不要求C型数据精确匹配。
【例5-14】 在“学生.DBF”中查找年龄为18岁的记录和出生年月为1984年7月24号的记录。
USE学生
INDEXON YEAR (DATE())-YEAR(出生年月) TAG nj
SEEK18
DISPALL FOR YEAR (DATE())-YEAR(出生年月)=18
INDEXON 出生年月 TAG cs
SEEK{^
DISP
【例5-15】 在教师.DBF中查找享受政府津贴的教师。
USE教师
INDEXON 政府津贴 TAG zfjt
SEEK.T.
DISP
SKIP
DISP
SKIP &&屏幕显示:已到文件尾。
【例5-16】 精确查找和模糊查找举例。
USE授课
INDEXON 课程号 TAG kch
SEEK“C
FOUND() &&屏幕显示:.T.
SETEXACT ON &&设置精确配置
SEEK“C
FOUND() &&屏幕显示:.F.
对表文件进行统计计算,包括计数、求和、求平均值、计算和汇总。
【命令】 COUNT[范围][FOR<条件>|WHIIE<条件>][TO<内存变量>]
【功能】 统计当前表文件中指定范围内满足条件的记录个数。
【说明】 省略全部选择项,则统计表文件中的所有记录;选择[TO<内存变量>],将统计结果存入内存变量中;否则,不保存统计结果,仅在屏幕上显示。
【例5-17】 统计“学生.DBF”中学生总人数和女生总人数。
USE学生
COUNTTO xszrs
COUNTFOR NOT 性别 TO nsrs
xszrs,nsrs &&屏幕显示:10 4
【命令】 SUM [范围][<N型字段表达式表>][FOR<条件>|WHILE<条件>][TO<内存变量表>|ARRAY<数组名>]
【功能】 在当前表文件中,对指定范围内满足条件的N型字段纵向求和。
【说明】
①选择[<N型字段表达式表>],对表文件中指定N型字段求和,各字段间用逗号隔开。
②求和结果存入内存变量或数组,但数组必须已经存在。
③省略所有选项,则对表文件中所有N型字段求和。
【例5-18】 对学生.DBF求学生入校总分之和;对教师.DBF教师工资总和。
USE 学生
SUM 入校总分 TO rxzf
SELECT 0
USE 教师
SUM 工资 TO gzzh
rxzf,gzzh &&屏幕显示:5763.00 11000.00
【命令】 AVERAGE [范围][<N型表达式表>][FOR<条件>|WHILE<条件>][TO<内存变量表> |ARRAY <数组名>]
【功能】 在当前打开表中,对指定范围内满足条件的N型字段求纵向平均值。
【说明】
①选择[<N型字段表达式表>],对表文件中指定N型字段求平均,各字段之间用逗号隔开。
②求平均结果存入内存变量或数组,但数组必须已经存在。
③省略所有选项,则对表文件中所有N型字段求平均。
【例5-19】 求“学生.DBF”中学生的平均年龄。
USE 学生
AVER year(date())-year(出生年月) to nl
nl &&屏幕显示:18.10
【命令】 CALCULATE [范围][<表达式表>][FOR<条件>|WHILE<条件>][TO<内存变量表> |ARRAY <数组名>]
【功能】 在当前打开表中,分别计算<表达式表>的值。
【说明】 <表达式表>由下列函数之一构成:求算术平均值函数AVG(N型表达式);求记录数函数CNT();求最大值函数MAX(<表达式>);求最小值函数MIN(<表达式>);求和函数SUM(N型表达式)。
【例5-20】 求“学生.DBF”中的入校总分最高分和最低分;求“教师.DBF”中的工资总和与平均工资。
USE 学生
CALCULATE MAX(入校总分), MIN(入校总分)
屏幕显示:MAX(入校总分) MIN(入校总分)
595 550
SELECT 0
USE 教师
CALCULATE SUM(工资),AVG(工资)
屏幕显示:SUM(工资) AVG(工资)
11000.00 2200.00
【命令】 TOTAL ON<关键字段名>T0 汇总文件名[范围][FOR<条件>|WHILE<条件>][FIELDS<N型字段名>]
【功能】 在当前表中,对指定范围内满足条件的记录按关键字段名分类汇总求和,并生成一个新表文件(又叫汇总文件)。
【说明】
①使用TOTAL之前,表文件必须按关键字排序或索引。
②选择FIELDS<N型字段名>,对指定N型字段分类求和;省略,则对所有N型字段分类求和。
③<关键字段名>若为C型字段时,把与关键字相同的第一条记录的字段值存入汇总文件中;若为N型字段,则把与关键字值相同的记录中该字段值求和后存入汇总文件中。
④如果汇总文件的字段宽度容纳不下汇总求和结果,系统将自动新表文件的N型字段宽度以容纳汇总结果。
【例5-21】 对教师.DBF表文件按性别统计工资情况,按职称统计工资情况。
USE教师 INDEX 教师 ORDER TAG xb
TOTALON 性别 TO xbgz FIELDS 工资
USExbzg
LIST
USE教师 INDEX 教师 ORDER TAG zc
LIST
TOTALON 职称 TO zcgz FIELDS 工资
USEzcgz
LIST
在当前工作区内对一个打开的表文件操作时,如果再打开第二个表文件,系统将自动关闭第一个表文件,这种只能对一个表进行的操作称为“单表操作”。在实际运用中,常常需要对两个或两个以上的表文件进行同时操作,这就涉及到多表操作问题。多表操作是以工作区为基础的。
1. 多工作区
(1)工作区
工作区是Visual FoxPro为当前正在使用的数据表文件开辟的一个内存区。在一个工作区内只能打开一个表文件,如果欲在同一个工作区内打开另一个表文件,系统将自动关闭前一个表文件后再打开第二个表文件。一个表文件也只能在一个工作区内打开。
Visual FoxPro提供了32767个工作区,各个工作区彼此独立,数据互不干扰。在任何时刻,操作对象只能占用一个工作区,这个工作区称为“当前工作区”。启动Visual FoxPro 后,系统默认1号工作区为当前工作区。利用选择工作区命令SELECT可以指定某个工作区为当前工作区。
每个工作区打开的表文件都有自己的记录指针,在当前工作区可以访问其他工作区上已经打开的表文件记录,但不能改变其他工作区记录指针和数据。
利用以下命令,可以在指定工作区打开一个表文件:
USE <表文件名> IN <工作区号>|<别名>
(2)别名
用户在建立表文件时要为其命名,当打开该文件后,还可以为它再取一个别的名字。别名可以代表工作区号或表文件名。系统定义前10个工作区的别名分别为:A、B、C、D、E、F、G、H、I、J。因此,用户不能把A、B、…J这10个字母作为表文件名使用。
可以利用以下命令为表文件指定别名:
USE <表文件名> ALIAS <别名>
例如:USE 学生 ALIAS xs && xs是学生.DBF的别名。
如果没有指定别名,系统默认表文件的主文件名为别名。
例如:USE 教师 && 教师也是教师.DBF的别名。
在主工作区上访问其他工作区上的数据,是实现多表文件之间数据处理的有效手段。由于多表文件中可能存在同名字段,因此,在当前工作区调用其它工作区中的表文件字段时,必须在其它表文件的字段名前面使用别名调用格式以示区别。
别名调用格式:工作区号->字段名 或:别名->字段名 或:别名.字段名
(3)选择工作区命令
【命令】 SELECT<工作区号>|<别名>
【功能】 指定工作区为当前工作区。
【说明】
①函数SELECT()返回当前工作区的区号。
②SELECT 0表示选当前未使用过的最小工作区号为当前工作区的区号。
③当前正在操作的工作区为主工作区,在主工作区上打开的表文件是主表。所有表文件操作命令都只能在当前工作区内进行。
④表文件操作完毕,可以使用USE命令依次关闭当前表文件;也可以使用CLOSE ALL命令关闭所有工作区的表文件。
【例5-22】 工作区、别名示例。
CLOSE ALL &&关闭所有已经打开表文件,回到1号工作区
SELECT() &&函数SELECT()返回当前工作区号为1
USE 学生 && 在1号工作区打开学生.DBF
SELECT 2
USE 教师 &&在2号工作区打开教师.DBF
DISP A.姓名,A.性别,姓名 && 显示1号工作区的姓名,性别和2号工作区的姓名
SELECT 0
USE 课程 &&在3号工作区打开课程.DBF
2. 数据工作期
数据工作期是一个用来设置数据工作环境的交互式窗口。每一个数据工作期中包含有打开的表、表索引和表之间的相互关系等的一组工作区。通过在数据工作期窗口中选择工作区,就可以打开这些相关表,实现快速查找。利用数据工作期建立的工作环境可以保存在一个视图文件中。需要时,打开视图文件就可以恢复已经建立的工作环境。
(1)数据工作期的组成
数据工作期由别名列表框、关系列表框和6个按钮组成。如图5-8所示。
图5-8 数据工作期窗口
别名列表框:用来显示已经打开的表文件,并可以从中选择当前表。
关系列表框:用来显示表文件之间的关联状态。
6个按钮:用来实现数据工作期的各种操作。
(2)数据工作期的打开
【命令】 SET VIEW ON
【菜单】 选择“窗口”菜单→“数据工作期”。
【功能】 打开已经建立的数据工作期。
【说明】 命令SET VIEW OFF表示关闭数据工作期。
【例5-23】 利用数据工作期窗口对表文件“教师.DBF”、“学生.DBF”进行查询。
(1)打开“窗口”→“数据工作期”→“打开”→选择数据库中的表“教师”→“确定”。
(2)选择“属性”按钮,→“字段筛选”教师号、姓名、职称→“确定”。
(3)选择“数据过滤器”设置过滤条件:教师.职称<>“讲师” →“确定”。
(4)选择“浏览”按钮,即可显示操作结果,如图5-9所示。
图5-9 查询结果之一
(5)选择数据库中的表“学生”→“确定”。
(6)选择“属性”按钮,→“字段筛选”学号、姓名、入校总分→“确定”。
(7)选择“数据过滤器”设置过滤条件:学生.入校总分=>580→“确定”。
(8)选择“浏览”按钮,即可显示操作结果,如图5-10所示。
图5-10 查询结果之二
1. 表的关联
一般情况下,各个工作区表文件的记录指针是彼此独立,互不影响。关联在两个表文件的记录指针之间建立一种临时关系,当一个表的记录指针移动时,与之关联的另一个表的记录指针也作相应的移动。建立关联的两个表,一个是建立关联的表,称为父表,另一个是被关联的表,称为子表。
关联并不真正生成一个表文件,只是形成了一种联系,与当前表文件建立联系的表由<别名>指定。建立关联后,在当前工作区执行了移动记录指针的命令后,如SKIP、GO、LIST、SEEK、FIND、LOCATE等,将引起多个工作区记录指针的移动,从而减低命令的执行速度。因此,在没有必要关联时,应及时取消关联。
(1)关联条件:建立关联的条件是首先为子表按某个关键字建立索引,然后比较两个表的两个关键字段值是否相等。当父表指针移动时,子表指针也会自动移动到满足关联条件的记录上。
(2)一对一关系:两个表之间的一对一关系中,父表的一个记录只能和子表的一个记录相关联,子表的一个记录也只能和父表的一个记录相关联。例如,一个职员有一个办公桌并且每一个办公桌被指定给一个职员。
(3)一对多关系:两个表之间的一对多关系中,父表的一个记录可以和子表的一个或多个记录相关联,但子表的一个记录只能和父表的一个记录相关联。例如,每一个父亲可以有多个孩子,但每一个孩子只能有一个父亲。
(4)多对一关系:两个表之间的多对一关系中,父表的多个记录可以和子表一个记录相关联,但子表的一个记录只能和父表的一个记录相关联。一般把”多”表作为父表最简单,因为父表中的任一记录,都可以在子表中找到唯一的记录与他联系。例如,家庭中爷爷、奶奶、姥爷、姥姥和孙子的关系,一个孙子只有一个爷爷、奶奶、姥爷、姥姥。
(5)多对多关系:两个表之间的多对多关系中,一个表的一个记录和相关表的多个记录相关联。例如,一个读者可以借了多本书,也可以是多本书对应该读者。一般把多对多关系撤分为多对一关系或一对多关系。
2. 用命令建立关联
【命令】 SET RELATION TO [<关联表达式1>]INTO <别名1>[[,<关联表达式2>]INTO<别名2>,……]][ADDITIVE]
【功能】 以当前表为父表与一个或多个子表建立关联。
【说明】
①被关联的字段必须先索引。当父表记录指针移动时,子表的记录指针定位在满足<关联表达式>值的第1个记录上,若找不到这条记录,记录指针就指向文件尾。
②选择ADDITIVE,保留以前的关联,否则,新建立的关联将取消先前建立的关联。
③不带任何选择项的SET RELATION TO将删除当前父表与其它子表的关联。
【例5-24】 利用表文件学生.DBF、选课.DBF、课程.DBF显示学生选课的课程名称与该课程的成绩情况。
分析:学生.DBF与选课.DBF之间可以通过学号建立关联,课程.DBF与选课.DBF之间可以通过课程号建立关联。且在建立第二个关联时,保留第一个关联。
CLEARALL
SELECT1
USE学生
INDEXON 学号 TAG xh
SELECT2
USE课程
INDEXON 课程号 TAG ckh
SELECT3
USE选课
SETRELATION TO 学号 INTO A
SETRELATION TO 课程号 INTO B ADDITIVE
LISTALL FIELDS A->姓名,B->课程名,成绩 OFF
3.“数据工作期”窗口建立关联
操作步骤:
(1)打开要建立关联的表文件。
(2)为子表按关联关键字建立索引或确定主控索引。
(3)选定父表工作区为当前工作区,并与一个或多个子表建立关联。
(4)系统默认建立的关联为“多对一关系”。有必要时,说明建立的关联为“一对多关系”。
4. 说明一对多关系的命令
【命令】 SET SKIP TO [<表别名1>[表别名2>…]]
【功能】 用在SET RELATION命令之后,说明已经建立的关联为一对多关系。
【说明】
①<表别名>表示一对多关系中位于多方的子表。
②不带任何选择项的SET SKIP TO将取消一对多关系,但不取消已经建立的多对一关系。
【例5-25】 利用表文件教师.DBF、授课.DBF、课程.DBF显示教师授课的课程名称与该课程的课时情况。
分析:题目涉及到三个表,以授课.DBF为父表,教师.DBF和课程.DBF是2个子表,属于“一对多关系”的关联问题。教师.DBF与授课.DBF以“教师号”作为关联条件,课程.DBF与授课.DBF以“课程号”作为关联条件。
CLEARALL
SELECT1
USE教师 && 子表1
INDEXON 教师号 TAG jsh
SELECT2
USE课程 && 子表2
INDEXON 课程号 TAG ckh
SELECT3
USE授课 && 父表
SETRELATION TO 教师号 INTO A
SETRELATION TO 课程号 INTO B ADDITIVE
SETSKIP TO B && 子表B为多方
LISTALL FIELDS A->姓名,A->职称,B->课程名,B->课时 OFF
表文件之间的连接称为物理连接,就是将两个表的相关字段组合起来,构成一个新的表。
【命令】 JOIN WITH<别名> TO <新表文件名> FOR<条件>[FIELDS<字段名表>]
【功能】 在当前表文件与指定别名的表文件之间建立联系。
【说明】
①被连接的两个表文件,一个是当前表文件,另一个是在<别名>中指定的工作区表文件。
②字句FOR<条件>是必选项,它是构成连接的条件。两个表文件必须按条件连接。
③选择[FIELDS<字段名表>],则生成的新表按字段顺序排列;省略[FIELDS<字段名表>],当前表的字段在前面,别名表文件的字段在后面。
④连接的过程是:从当前表文件的第一条记录开始,在指定的别名工作区中查找符合条件的记录,每找到一条,就将当前记录与别名工作区找到的记录连接生成一个新记录并存入新表文件中。重复上述操作,直到把当前工作区中的所有记录处理完毕为止。
⑤新生成的表文件的扩展名为.DBF,且只有将其打开后,才能对其操作。
【例5-25】 根据“学生”、“选课”和“课程”三个表文件,新生成一个表“学生课程”,新表中包含由学号,姓名,性别,课程名称、课时数等字段。
分析:新表“学生课程”由“学生”和“选课”两个表连接生成一个“学生选课”新表,连接的条件是学号。然后,再由“学生选课”和“课程” 两个表连接生成“学生课程”新表,连接的条件是课程号。
SELECT 1
USE 学生
SELECT 2
USE 选课
JOIN WITH A TO 学生选课 FOR 学号=A->学号 FIELDS A->学号,A->姓名,A->性别,课程号,成绩
SELECT 3
USE 学生选课
SELECT 4
USE 课程
JOIN WITH C TO 学生课程 FOR 课程号=C->课程号 FIELDS C->学号,C->姓名,C->性别,课程名,课时,C->成绩
USE 学生课程
LIST
利用表更新命令,则不必进行关联,而是直接利用一个表文件数据来修改另一个表文件数据。
【命令】 UPDATE ON<关键字段> FROM <别名> REPLACE <字段名1> WITH <表达式1>[,<字段名2> WITH <表达式2>……][RANDOM]
【功能】 利用<别名>表的表达式值来更新当前表文件中记录的字段值。
【说明】
①<关键字段>为两个表文件必须共有的。当前表的字段为被更新字段,<别名>表的字段为更新字段。
②选择[RANDOM],则只要求当前表按关键字段索引,否则要求两个表都必须按<关键字段>排序或索引。
③若<别名>指定的表文件中有多个记录具有相同的关键字段值,那么最后一条记录对当前表的更新有效;如果在当前表中有多个具有相同关键字段的记录,则只更新第一条记录。
【例5-26】 先将表文件“教师.DBF”复制为“教师-1.DBF”,然后给“教师-1.DBF”表增加一个字段“课程号”,并用“授课.DBF”表中的“课程号”更新“教师-1”表的“课程号”。
SELECT 1
USE 教师
COPY TO 教师-1
USE 教师-1
ALTER TABLE 教师-1 ADD 课程号 C(4)
INDEX ON 教师号 TAG jsh1
SELECT 2
USE 授课
INDEX ON 教师号 TAG jsh2
SELECT 1
UPDATE ON 教师号 FROM 授课 REPLACE 课程号 WITH B->课程号 RANDOM
LIST
1. 建立索引的正确命令是______。
A) SORT INDEX B) INDEX SORT
C) SORT TO INDEX TO D)INDEX TO SORT TO
2. 在Visual FoxPro中,执行下列命令序列后,打开的文件是______。
SELECT 1
USE 学生
USE 教师
A) 学生 B)教师 C)学生和教师 D)一个也没有打开
3. 在当前表中,字段性别的数据类型为L型,如果查找第5个女同学的记录,应使用命令______。
A) LOCATE FOR性别=“女”NEXT 5
B) LOCATE FOR“女” NEXT 5
C) LOCATE FOR NOT性别 NEXT 5
D) LIST FOR NOT性别 AND NEXT 5
4. 下列命令使用不正确的是______。
A) SORT ON 姓名 TO xm FOR 性别=“男”
B) SORT ON 备注 TO bz
C) INDEX ON 工资 TAG gz
D) INDEX ON 姓名 TAG xm DESCENDING
5. 教师表与教师索引文件已经打开,把记录指针定位在第1个工资高于800元的记录上的命令是______。
A) SEEK工资>800 B)FIND工资>800
C) FIND FOR工资>800 D)LOCATE FOR工资>800
6. 在Visual FoxPro中,使用SEEK命令时,表文件要求______。
A) 排序 B) 建立索引 C) 排序或建立索引 D)无要求
7. 下面说法有误的是______。
A) 主索引是设定有主关键字的索引,主关键字能唯一确定记录的顺序,它不允许在指定字段中出现重复值
B) 执行排序操作后,记录在排序文件中形成的顺序是一种物理顺序
C) 一个数据表只能创建一个主索引,自由表不能创建主索引
D) 一个数据表可以创建多个主索引,自由表只能创建一个主索引
8. 以性别升序排列,性别相同时以入校总分升序排列,索引标识为普通索引的命令是______。
A) INDEX ON 性别+STR(入校总分,3) TAGxbzfa
B) INDEX IN 性别+STR(入校总分,3) TAGxbzfa
C) INDEX ON 性别-STR(入校总分,3) TAGxbzfa
D) INDEX ON 性别+入校总分TAG xbzfa
9. 利用表设计器建立或修改索引的操作步骤是______。
A) 选择“文件”菜单→“新建”命令→“表”选项→“格式”菜单→表设计器→“索引”选项卡→“索引名”→“排序”→“类型”→“表达式”→确定
B) 选择“文件”菜单→“打开”命令→“表”选项→“格式”菜单→表设计器→“索引”选项卡→“索引名”→“排序”→“类型”→“表达式”→确定
C) 选择“文件”菜单→“打开”命令→“表单”选项→“显示”菜单→表单设计器→“索引”选项卡→“索引名”→“排序”→“类型”→“表达式”→确定
D) 选择“文件”菜单→“打开”命令→“表”选项→“显示”菜单→表设计器→“索引”选项卡→“索引名”→“排序”→“类型”→“表达式”→确定
10. 对打开的索引文件中指定主控索引文件,或对打开的复合索引文件中设置主控索引的命令是______。
A) SET ORDER TO 0 B) SET ORDER TO
C) SET ORDER TO xbxha D) SET INDEX TO xbxha
11. 执行命令SELECT 0后,选择的工作区是______。
A) 选择了0号工作区 B) 选择了空闲的最小号工作区
C) 选择了一个空闲的工作区 D) 显示出错信息
12. 在“教师.DBF”中查找职称是教授的所有女教师的命令是______。
A) LOCATE FOR 职称=“教授”AND性别=“女”
B) LOCATE ALL FOR 职称=“教授”AND性别=“女”
C) LOCATE FOR 职称=“教授”OR性别=“女”
D) LOCATE ALL FOR 职称=“教授”OR 性别=“女”
13. 在“职工表.DBF”中查找年龄为45岁的记录的命令序列是______。
A) USE 职工表
INDEX ON YEAR (DATE())-YEAR(出生年月) TAG nj
SEEK 45
B) USE 职工表
SORT ON YEAR (DATE())-YEAR(出生年月) TAG nj
SEEK 45
C) USE 职工表
INDEX ON YEAR (DATE())-YEAR(出生年月) TAG nj
SEEK “
D) USE 职工表
SORT ON YEAR (DATE())-YEAR(出生年月) TAG nj
SEEK “
14. 求“学生成绩.DBF”中的总分的最高分、总分之和与总分平均的命令序列是______。
A) USE 学生成绩
CALCULATE MAX(总分), MIN(总分),CALCULATE SUM(总分),AVG(总分)
B) USE 学生成绩
CALCULATE 最高分,最低分),总分和,总分平均
C) USE 学生成绩
CALCULATE MAX(总分), MIN(总分),SUM(总分),AVG(总分)
D) USE 学生成绩
CALCULATE MAX总分, MIN总分,CALCULATE SUM总分,AVG总分
1. 在Visual FoxPro中,建立复合索引文件,索引标识为普通索引命令是 。
2. 表中各种数据的定义或设置信息(包括表的属性、字段属性、记录规则、表间
关系以及参照完整性等)保存在 中。
3. 使用顺序可以是 ,也可以是 。记录指针在表记录中的移动是按 进行的。
4. 对表文件进行追加、修改等操作后,对于打开的索引文件或随着表文件打开而打开的复合索引文件,系统 ,而对于那些没有打开的索引文件则变得无意义了。为了使这些索引文件仍然有效,可以利用 命令,使其与修改后表文件保持一致。
5. 执行命令FOUND()后,如果记录找到,则函数返回值 ;否则函数返回值 。
6. 索引查询要求被查询表文件建立并打开 。
7. 命令AVERAGE的功能是在当前打开表中,对指定范围内满足条件的 型字段求 。
8. 使用TOTAL命令之前,表文件必须按关键字 。<关键字段名>若为C型字段时,则把与关键字相同的 记录的字段值存入汇总文件中;若为N型字段,则把与关键字值相同的记录中 存入汇总文件中。
9. 在一个工作区内只能打开 表文件,如果欲在同一个工作区内打开另一个表文件,系统将 前一个表文件后再打开第二个表文件。
10. 在当前工作区调用其它工作区中的表文件字段时,必须在其它表文件 使用别名调用格式。
11. 数据工作期是一个用来设置 的交互式窗口。利用数据工作期建立的工作环境可以保存在一个 中。需要时,打开 文件就可以恢复已经建立的 。
12. 关联是在两个表文件的 之间建立一种 ,当一个表的记录指针移动时,与之关联的另一个表的记录指针 的移动。建立关联的两个表,一个是建立关联的表,称为 ,另一个是被关联的表,称为 。
13表文件之间的连接称为 ,是将两个表的相关字段组合起来,构成一个 。
14. 表文件连接的过程是:从当前表文件的 记录开始,在指定的 工作区中查找符合条件的记录,每找到一条,就将当前记录与别名工作区找到的记录连接 一个新记录并 新表文件中。重复上述操作,直到把当前工作区中的 处理完毕为止。
联系客服