FoxPro For Windows http://cc.synu.edu.cn 1
第 6讲 数据库的高级操作
数据库文件的排序
数据库文件的索引
数据库文件的检索
数据的统计与运算
FoxPro For Windows http://cc.synu.edu.cn 2
数据库记录的物理顺序(记录号)取决于数据输入的顺序。
排序:数据库中记录按照某字段值大小重新排列,作为排序依据的字段
称为? 关键字 ?。排序后得到一个 新 数据库,原数据库不变。
数据库文件的排序
SORT ON <字段名 1> [/A][/D][/C][,<字段名 2>…… ] TO<数据库名 >
【 说明 】
?默认按字段升序 排序, /A:升序 /D:降序 /C:不区分字母的大小写, 默认区分 。
?排序依据可以是 多个字段, 中间隔以逗号 。
?可以加条件 For 或 while,对满足条件的记录排序
?可以加 field <field list>,决定生成新数据库的结构 。
【 例 】 USE student
SORT ON SNO TO stud1
USE stud1
LIST
SORT TO stud2 ON birthday,score/D FOR sex="女 "
FoxPro For Windows http://cc.synu.edu.cn 3
? 排序后生成了许多内容相同,仅排列顺序不同的 新数据库文件,
造成数据冗余,排序过程中所需磁盘空间为原文件的三倍。
? 索引是不改变纪录的物理顺序,按照索引表达式值使数据库中的
纪录有序排列,它生成一个 索引文件,数据变化时,索引文件自
动按索引表达式值进行调整。
数据库文件的索引
索引文件:由按照一定的逻辑顺序排列的关键字段 ( 或表达式 ),
和每个字段值所在的记录号组成 。
以 SNO为关键字的索引文件 SNO.IDX:
查找时,先在索引文件中快速查到
要查的关键字,然后根据相对应的
记录号在数据库文件中快速定位到
相应的记录上。
SNO 记录号
990101 1
990102 6
990103 4
990104 3
990105 2
990106 5
FoxPro For Windows http://cc.synu.edu.cn 4
.IDX,CDX 结构,CDX 非结构
use student use student use student
inde on sno to sno inde on sno tag sno inde on sno tag sno of stu
inde on name to name inde on name tag name inde on name tag name of stu
索引文件 sno.IDX 索引文件 student.cdx 索引文件 stu.cdx
索引文件 name.IDX
Sno Sno
name
Sno
namename
【 例 】
单索引文件(,IDX):只能包含一个索引。
复合索引文件(,CDX):结构复合索引文件(与数据库文件主名同名)
非结构复合索引文件
单索引文件,INDEX ON <关键字表达式 > TO <单索引文件名 >
复合索引文件:
INDEX ON <关键字表达式 > TAG <索引标识 > [OF <复合索引文件名 >]
[ASCENDING | DESCENDING][UNIQUE]
FoxPro For Windows http://cc.synu.edu.cn 5
【 例 】 索引表达式
USE student
INDEX ON score TO score &&score.idx
INDEX ON -score TO sco &&按 score 降序
多个字段索引表达式需转换成同一类型后相加。
单索引只有升序,数值表达式前加‘ -?号实现降序,字符型不可以。
INDEX ON sex+STR(score) TO sex &&sex.idx
INDEX ON name+DTOC(brithday) TO bri
INDEX ON 数学 +语文 TO sy
INDEX ON 性别 TOSY1 UNIQUE
唯一索引,当几条纪录索引表达式值相同时,只取其中记录号最小的。
数值型取其和做关键字的值。
additive控制建立索引或打开索引时,以前的索引并不关闭。
FoxPro For Windows http://cc.synu.edu.cn 6
字符转日期函数,CTOD(<字符表达式 >)
日期转字符函数,DTOC(<日期型表达 >)
数值转字符串函数,STR(<数值表达式 >[,<长度 >][,<小数位数 >]
字符串转数值函数,VAL(<字符串表达式 >)
【 例 】
Str(350)
Str(120,3)
Str(120.456,7,3)
Str(34.45,2)
Str(34.55,2)
Str(121.3,2)
CTOD(“02/11/03”)
DTOC(date())
val("12")
val("a12")
val("12a")
相关函数
FoxPro For Windows http://cc.synu.edu.cn 7
2)打开索引:
a,建立索引文件时,同时打开了这个索引文件。
b.结构复合索引文件随数据库自动打开。
c.在打开数据库的同时打开索引文件。
USE <数据库文件 > INDEX <索引文件名表 >
【 例 】 USE STUDENT INDE Score,sex
d.在打开数据库之后打开索引文件 。
SET INDEX TO <索引文件名表 > && 数据库文件必须先打开。
【 例 】 USE STUDENT
SET INDEX TO Score,sex
3)关闭索引
SET INDEX TO 关闭当前工作区中的所有索引文件。
CLOSE INDEX 关闭当前工作区中的所有索引文件。
CLOSE DATABASES 关闭所有数据库及其索引文件。
USE 关闭当前工作区的数据库及其索引文件。
FoxPro For Windows http://cc.synu.edu.cn 8
5) REINDEX 当数据库的纪录发生变化时,需重建索引,
INDEX和 REINDEX 忽略 set delete命令的设置。
4)控制索引,
同时打开多个索引文件时,只有一个是主索引,默认第一个。
可用 SET ORDER TO命令改变主索引。
【 例 】 USE STUDENT INDEX Score,Sex
SET ORDER TO 2 &&Sex.IDX
SET ORDER TO 2 OF ST1
SET ORDER TO 0 &&关闭主索引以物理顺序排列
use student
inde on score to score1
append &&80
List
依据关键字值,新追加记录
加入索引文件。
use student
append &&80
set inde to score1
list
REINDEX
list
56
60
75
80
92
56
60
75
92 56
60
75
80
92
FoxPro For Windows http://cc.synu.edu.cn 9
3,索引后指针定位:
GO TOP|BOTT, SKIP 逻辑定位
GO 1 物理定位
排序 索引
文件类型, dbf, i d x, c d x
文件单独使用 可以 不可以
物理次序 ( 记录号 ) 改变 不变
自动更新 不能 能
检索速度 慢 快
小结:
1,索引与排序比较:
2.命令格式:
SORT TO <排序文件名 > ON <字段 1> [/A][/D][/C] 多个字段用?,?间隔。
INDEX ON <表达式 > TO <索引文件名 > 多个字段转换成字符型用? +”连接。
56 3
60 4
75 2
80 5
92 1
Score1.idx
FoxPro For Windows http://cc.synu.edu.cn 10
物理检索,LOCATE [范围 ] FOR <条件 >
索引检索,FIND <字符串 >/<数值 >
SEEK <表达式 >
数据库文件的检索
检索成功, 指针指向首条符合条件的记录,FOUND()函数为,T.,EOF()为,F.,
RECNO()函数可返回该记录的记录号;
检索失败,记录指针指向文件尾部,FOUND()函数为,F.,而 EOF()为,T.,且
系统显示提示 "NO FOUND"。
注意:
?必须在打开索引文件后使用;
?不能在非关键字之外的字段中进行查找;
?find,seek的缺点:只能按确定值查找,不能使用范围条件。
FoxPro For Windows http://cc.synu.edu.cn 11
【 例 】
USE STUDENT
INDE ON NAME to NAME
INDE ON SCORE to SCORE
SET ORDER TO NAME
FIND 赵 辉
DISPLAY
X="赵 辉 "
FIND &X
DISPLAY
SET ORDER TO SCORE
SEEK 600
DISPLAY
【 例 】 检索条件表达式
Loca for sex=?男’,and,english>80
locate for 姓名 =“张军?
Find 张军
seek,张军? Seek {02/12/25}
Seek,t,
Find 528
Seek 528
x=?赵辉’
y=261
seek x
seek y
Find &x
× find &y × seek 姓名 =“张军?
FoxPro For Windows http://cc.synu.edu.cn 12
释疑:
▲ LOCATE命令是按条件查询,FIND和 SEEK命令必须先建立索引,
不能脱离索引使用,按索引关键字的确定值查询 。 注意区别,
LOCATE FOR姓名 =“张军?,而 FIND与 SEEK不能用 FIND姓名 ="张
军 "或 SEEK姓名 ="张军 ",应使用命令 FIND 张军 或 SEEK "张军 "
▲ 执行 LOCATE命令后,继续查找下一个满足条件的记录应使用
CONTINUE命令,不能再使用 LOCATE命令。执行 SEEK, FIND
命令后,继续查找下一个满足条件的记录应使用 SKIP命令,
▲ SEEK命令除了比 FIND命令查找的数据类型多之外,还要注意 SEEK
命令后面可以是 表达式,而 FIND命令后只能跟 字符串 或 数值 。在对
字符型常量查找时,SEEK必须加 定界符, FIND可加也可不加。
▲ 使用 FIND命令查询时,如果被查询的值存在变量中,必须使用宏代
换。 例如, MNAME=“张宏?,
FIND &MNAME
或 SEEK MNAME.
FoxPro For Windows http://cc.synu.edu.cn 13
宏替换函数, &<字符型变量 >[.<字符串常量 >]
唯一一种没有括号的函数,参数为字符型变量,函数值为该变量所
表示的字符串去掉定界符内的部分。
,是宏替换函数和后面字符串常量的 分隔符 。
相关函数
【 例 】 A=‘123’
A+100 &&operator/operand type mismatch
&A &&123
&A+100 &&223
&A.45+100 &&12445
FoxPro For Windows http://cc.synu.edu.cn 14
? 子串搜索函数,
AT(<字符串表达式 1>,<字符串表达式 2>[,<数值 >])
RAT(<字符串表达式 1>,<字符串表达式 2>[,<数值 >])
AT()返回字符串 1在字符串 2中从左边的开始位置,若字符串 2不包含
字符串 1,则返回值为 0。 RAT从右边开始。
【 例 】?at("for","FoxPro 2.6 for Windows") &&12
Rat(‘人民’,’中华人民共和国的人民’,2) &&5
一定要注意一个汉字占两个字符的位置。
?取子串函数,
SUBSTR(<字符串 >,<起始位置 >[,<字符个数 >])
?取左子串函数,LEFT(<字符串 >,<字符个数 >)
?取右子串函数,RIGHT(<字符串 >,<字符个数 >)
【 例 】 str="FoxPro 2.6 for Windows"
subs(str,12,3) &&for
left(str,10) &&FoxPro 2.6
FoxPro For Windows http://cc.synu.edu.cn 15
? 删除字符串首、尾空格函数,
ALLTRIM(<字符表达式 >)
TRIM() LTRIM()
? 空格函数, SPACE(<数值表达式 >)
【 例 】?‘ abc’+space(3)+ ‘def’ &&abc def
【 例 】 USE GZ
INDE ON 姓名 +STR(奖金,3) TO GZW
FIND 李力 80
? FOUNT() &&,f.
INDE ON TRIM(姓名 )+LTRIM(STR(奖金,3))
姓名 +STR(奖金,3) 记录号
李大为 60 3
李力 80 4
李小蓝 50 6
……,
FoxPro For Windows http://cc.synu.edu.cn 16
1)模糊、精确的区别:
给出查询内容的全部为精确,SEEK‘张松’
给出查询内容的部分为模糊,SEEK‘张’
2)模糊查询的实现:
SET EXACT OFF
LOCA FOR 姓名 =‘张’
FOR AT(“张?,姓名 )<>0
FOR SUBS(姓名,1,2)=‘张’
FOR,张? $姓名
FIND 张
SEEK ’张’
注意:一个汉字
占两个字符!!
模糊查询
FoxPro For Windows http://cc.synu.edu.cn 17
【 例 5.25】 实现在已建立索引文件的数据库中按学号连续查询。
SET TALK OFF
USE cjk INDE sno &&已经建立索引文件 sno
DO WHILE,T.
CLEAR
ACCEPT "请输入学号," TO kh
SEEK kh
IF FOUND( )
sno,"的成绩如下,"
,语文:?,yw
,数学:?,sx
,英语:?,yy
ELSE
"对不起,库中没有这个人 "
ENDIF
WAIT "继续吗( Y/N)? " TO jx &&修改循环条件
IF UPPER(jx)= "N"
EXIT
ENDIF
ENDDO
USE
SET TALK ON
FoxPro For Windows http://cc.synu.edu.cn 18
? 统计满足条件的记录个数
COUNT [to<内存变量 >]
【 例 】
USE student
COUNT FOR sex=‘女’ TO x
DELETE FOR sex=‘男’
COUNT TO y
SET DELETED ON
COUNT TO y
RECALL ALL
SET FILTER TO sex=‘男’
COUNT TO x
x
数据统计与计算
统计结果与 set dele 的状态有关
统计结果显示在状态栏上
FoxPro For Windows http://cc.synu.edu.cn 19
? 数值型字段纵向求和
SUM[<字段名表 >][TO<内存变量表 >]
【 例 】 SUM
SUM score
SUM FOR sex=‘女’ TO X,Y
SUM FOR sex=‘女’ TO X 注意:此时提示语法错,如缺
省字段表,则内存变量表要和库中数值型数据个数一致。
求和结果与 set dele 的状态有关,为 ON,则不参与求和,
Set talk on 求和结果显示在背景窗上,为 off则不显示。
?如何求数值字段横向和?
Repl zf with yw+sx+yy
FoxPro For Windows http://cc.synu.edu.cn 20
? 对数值型字段纵向求平均值
AVERAGE[<字段名表 >][TO<内存变量表 >]
? 和 sum用法一样,求数值型字段的平均值 。
FoxPro For Windows http://cc.synu.edu.cn 21
? 分类汇总
TOTAL ON <关键字 >TO<文件名 >
必须先索引或排序 。 只对数值型字段分类汇总, 而其它类型字段只取
相同关键字第一条记录的字段值, 所生成目标文件除不包括源文件的
备注字段外, 保留源文件的结构 。
【 例 】
USE zg
INDE on 部门 to bm
TOTAL on 部门 to hjk
USE hjk
LIST
按部门索引后的数据库:
部门 姓名 工资
计算中心 丹阳 1200
计算中心 王力 1350
教务处 阳平 1300
教务处 李立 1400
汇总后新数据库 hjk:
部门 姓名 工资
计算中心 丹阳 2550
教务处 阳平 2700