Visual FoxPro
1
i s u a l
F
V
o x P r o
Visual FoxPro
2
6.1 SQL语言概述
6.2 数据定义
6.3 数据查询
6.4 数据操纵
Visual FoxPro
3
20世纪 80年代初, 美国国家标准协会 ( ANSI) 开
始着手制定 SQL标准, 最早的 ANSI标准于 1986年完
成, 它也被叫做 SQL86。 SQL标准的出台使 SQL作
为标准关系数据库语言的地位得到了加强 。 随后,
SQL标准几经修改和完善, 其间经历了 SQL89、
SQL92,一直到最近的 SQL99等多个版本, 每个新
版本都较前面的版本有重大改进, SQL99更是包含
了对诸如面向对象, 递归, 触发器等概念的支持 。
目前, 各主流数据库产品采用的 SQL标准是 1992年
制定的 SQL92。
6.1 SQL语言概述
Visual FoxPro
4
按照 ANSI的规定, SQL被作为关系数据库的标
准语言 。 SQL语句可以用来执行各种各样的操作 。
目前流行的关系数据库管理系统, 如 Qracle,Sybase、
SQL Server,Visual FoxPro等都采用了 SQL语言标
准, 而且很多数据库都对 SQL语句进行了再开发和
扩展 。
SQL语言 具有如下 特点:
( 1) SQL是一种一体化的语言 。 尽管设计 SQL的最初
目的是查询, 数据查询也是其最重要的功能之一,
但 SQL决不仅仅是一个查询工具, 它集数据定义,
数据查询, 数据操纵和数据控制功能于一体, 可以
独立完成数据库的全部操作 。
( 2) SQL语言是一种高度非过程化的语言 。 它没有必
要一步步地告诉计算机, 如何, 去做, 而只需要描
述清楚用户要, 做什么,, SQL语言就可以将要求
交给系统, 自动完成全部工作 。
Visual FoxPro
5
( 3) SQL语言非常简洁 。 虽然 SQL语言功能很强,
但 它只有为 数不多的 9 条命 令,CREATE,
DROP, ALTER, SELECT, INSERT,
UPDATE,DELETE,GRANT,REVOKE。 另
外 SQL的语法也非常简单, 它很接近英语自然语
言, 因此容易学习和掌握 。
( 4) SQL语言可以直接以命令方式交互使用, 也
可以嵌入到程序设计语言中以程序方式使用 。 现
在很多数据库应用开发工具都将 SQL语言直接融
入到自身的语言之中, 使用起来更方便, Visual
FoxPro就是如此 。 这些使用方式为用户提供了灵
活的选择余地 。 此外, 尽管 SQL的使用方式不同,
但 SQL语言的语法基本是一致的 。
Visual FoxPro
6
Visual FoxPro在 SQL方面支持 数据定义, 数
据查询和数据操纵功能, 但在具体实现方面也
存在一些差异 。 另外, 由于 Visual FoxPro自身
在安全控制方面的缺陷, 所以它没有提供数据
控制功能 。
SQL虽然在各种数据库产品中得到了广泛的
支持, 但迄今为止, 它只是一种建议标准, 各
种数据库产品中所实现的 SQL在语法, 功能等
方面均略有差异, 本章讲述 Visual FoxPro 中
SQL的语法, 功能与应用 。
Visual FoxPro
7
6.2.1 建立表结构
CREATE TABLE|DBF < 表名 1> [NAME < 长表名>][FREE]
(<字段名 1> <类型 >(<宽度 >[,<小数位数 >])[NULL|NOT
NULL]
[CHECK <条件表达式 1>[ERROR<出错显示信息 >]]
[DEFAULT < 表达式 1>][PRIMARY KEY |UNIQUE]REFERENCES <表名 2>[TAG <标识 1>]
[<字段名 2><类型 >(<宽度 >[,<小数位数 >])[NULL|NOT
NULL]
[CHECK <条件表达式 2>[ERROR<出错显示信息 >]]
[DEFAULT < 表达式 2>][PRIMARY KEY |UNIQUE]REFERENCES<表名 3>[TAG<标识 2>]
…… )|FROM ARRAY <数组名 >
6.2 数据定义
Visual FoxPro
8
表名 1,要建立的表的名称 。
FREE,如果当前已经打开一个数据库, 这里所建立
的新表会自动加入该数据库, 除非使用参数
,FREE”说明该新表作为一个自由表不加入当前
数据库 。 如果没有打开的数据库, 该参数无意义 。
字段名 1,字段名 2,……, 所要建立的新表的字段
名, 在语法格式中, 两个字段名之间的语法成分
都是对一个字段的属性说明, 包括:
类型 —— 说明字段类型 。
宽度及小数位数 —— 字段宽度及小数位数 。
NULL,NOT NULL—— 该字段是否允许, 空值,,
其默认值为 NULL,即允许, 空, 值 。
CHECK 条件表达式 —— 用来检测字段的值是否有效,
这是实行数据库的一种完整性检查 。
Visual FoxPro
9
ERROR 出错显示信息 —— 当完整性检查有错误, 即
条件表达式的值为假时的提示信息 。 应当注意, 当
为一个表的某个字段建立了实行完整性检测的条件
表达式后, 在对该数据表输入数据时, 系统会自动
检测所输入的字段值是否使条件表达式为假, 当有
一个数据使其为假时, 系统自动显示这里所提示的
出错信息 。
DEFAULT 表达式 —— 为一个字段指定的默认值 。
PRIMARY KEY—— 指定该字段为关键字段, 非数据
库表不能使用该参数 。
UNIQUE—— 指定该字段为一个侯选关键字段 。 注意,
指定为关键或侯选关键的字段都不允许出现重复值,
这称为对字段值的唯一性约束 。
Visual FoxPro
10
REFERENCES 表名 —— 这里指定的表作为新建表的
永久性父表, 新建表作为子表 。
TAG 标识 —— 父表中的关联字段, 若缺省该参数, 则
默认父表的主索引字段作为关联字段 。
数组名 —— 用指定数组的值建立输入表 。
从以上命令格式可以看出, 用 CREATE TABLE命令
建立表可以完成用表设计器完成的所有功能 。 除了
建立表的基本功能外, 它还包括满足实体完整性的
主关键字 ( 主索引 ) PRIMARY KEY,定义域完整
性的 CHECK约束及出错提示信息 ERROR,定义默
认值的 DEFAULT等 。 另外还有描述表之间联系的
FOREIGN KEY和 REFERENCES等 。
Visual FoxPro
11
例 利用 SQL命令建立学生管理数据库, 其中包含 3个
表:学生表, 选课表和课程表 。
( 1) 用 CREATE命令建立数据库 。
CREATE DATABASE D:
( 2) 用 CREATE命令建立学生表 。
CREATE TABLE 学生 (学号 C(5) PRIMARY KEY,姓
名 C(8),;
入学成绩 N(5,1) CHECK(入学成绩 >0) ERROR ″成绩
应该大于 0! ″)
Visual FoxPro
12
( 3) 建立课程表 。
CREATE TABLE 课程 (课程号 C(5) PRIMARY KEY,课
程名 C(20),学分 N(1))
( 4) 建立选课表 。
CREATE TABLE 选课 (学号 C( 5), 课程号 C(5),;
成绩 I CHECK(成绩 >=0 AND 成绩 <=100);
ERROR″成绩值的范围 0~100! ″DEFAULT 60,;
FOREIGN KEY 学号 TAG 学号 REFERENCES 学生, ;
FOREIGN KEY 课程号 TAG 课程号 REFERENCES 课
程
Visual FoxPro
13
利用 SQL命令建立数据库
Visual FoxPro
14
用 SQL CREATE命令新建的表自动在最小可用
工作区打开, 并可以通过别名引用, 新表的打开方
式为独占方式, 忽略 SET EXCLUSIVE的当前设置 。
如果建立自由表 ( 当前没有打开的数据库或使用
了 FREE), 则很多选项在命令中不能使用, 如
NAME,CHECK,DEFAULT,FOREIGN KEY、
PRIMARY KEY和 REFERENCES等 。
注意
Visual FoxPro
15
6.2.2 删除表
删除表的 SQL
DROP TABLE <表名 >
DROP TABLE命令直接从磁盘上删除所指定的表文
件 。 如果指定的表文件是数据库中的表并且相应
的数据库是当前数据库, 则从数据库中删除了表 。
否则虽然从磁盘上删除了表文件, 但是记录在数
据库文件中的信息却没有删除, 此后会出现错误
提示 。 所以要删除数据库中的表时, 最好应使数
据库是当前打开的数据库, 在数据库中进行操作 。
Visual FoxPro
16
6.2.3 修改表结构
修改表结构的命令是 ALTER TABLE,该命令有
3种格式 。
格式 1:
ALTER TABLE <表名 1>
ADD|ALTER [COLUMN] <字段名 ><字段类型 >[(<宽
度 >[,<小数位数 >])]
[NULL | NOT NULL][CHECK < 逻辑表达式 >
[ERROR<出错显示信息 >]]
[DEFAULT <表达式 >][PRIMARY KEY|UNIQUE]
[REFERENCES <表名 2>[TAG <标识名 >]]
例 为课程表增加一个整数类型的学时字段 。
ALTER TABLE 课程 ;
ADD 学时 I CHECK(学时 >16) ERROR ″学时应该大
于 16! ″
Visual FoxPro
17
格式 2:
ALTER TABLE <表名 >
ALTER [COLUMN] <字段名 > [NULL|NOT NULL]
[SET DEFAULT <表达式 >[SET CHECK <逻辑表达
式 > [ERROR <出错显示信息 >]]
[DROP DEFAULT][DROP CHECK]
该格式命令主要用于定义, 修改和删除有效性规则以
及默认值定义 。
例 删除学时字段的有效性规则 。
ALTER TABLE 课程 ALTER 学时 DROP CHECK
Visual FoxPro
18
格式 3:
ALTER TABLE <表名 > [DROP [COLUMN] <字段 >
[SET CHECK<逻辑表达式 >[ERROR <出错显示信息 >
[DROP CHECK]
[ADD PRIMARY KEY <表达式 > TAG <索引标识 >
[FOR <逻辑表达式 >]]
[DROP PRIMARY KEY]
[ADD UNIQUE <表达式 > [TAG <索引标识 > [FOR <逻
辑表达式 >]
[DROP UNIQUE TAG <索引标识 >
[ADD FOREIGN KEY <表达式 > TAG <索引标识 >
[FOR <逻辑表达式 >]]
Visual FoxPro
19
REFERENCES <表名 2>[TAG <索引标识 >]]
[DROP FOREIGN KEY TAG <索引标识 >[SAVE]]
[RENAME COLUMN <原字段名 > TO <目标字段名 >]
该 格 式 的 命 令 可 以 删 除 指 定 字 段 ( DROP
[COLUMN]), 修改字段名 (RENAME COLUMN)、
修改指定表的完整性规则, 包括主索引, 外关键字,
候选索引及表的合法值限定的添加与删除 。
例 删除课程表中的学时字段 。
ALTER TABLE 课程 DROP COLUMN 学时
Visual FoxPro
20
Visual FoxPro的 SQL SELECT命令的语法格式是,
SELECT [ALL|DISTINCT]
[<别名 >.]<选项 >[AS <显示列名 >][,[<别名 >.]<选项
>[AS <显示列名 >]… ]
FROM [<数据库名 !]<表名 >[[AS] <本地别名 >]
[[INNER | LEFT [OUTER] |
RIGHT[OUTER]|FULL [OUTER]
JOIN <数据库名 >!]<表名 >[[AS]<本地别名 >][ON <
联接条件 >… ]
[[INTO <目标 >|[TO FILE<文件名 >][ADDITIVE]
|TO PRINTER [PROMPT]|TO SCREEN]]
6.3 数据查询
Visual FoxPro
21
[PREFERENCE<参照名
>][NOCONSOLE][PLAIN][NOWAIT]
[WHERE <联接条件 1>[AND <联接条件 2>… ]
[AND|OR <过滤条件 1>[AND|OR <过滤条件 2>… ]]]
[GROUP BY < 分组列名 1>[,< 分组列名
2>… ]][HAVING <过滤条件 >]
[UNION[ALL]SELECT命令 ]
[ORDER BY <排序选项 1>[ASC|DESC][,<排序选项
2>[ASC|DESC]… ]]
Visual FoxPro
22
6.3.1 基本查询
所谓基本查询是指无条件查询, 其格式是:
SELECT [ALL|DISTINCT]
[<别名 >.]<选项 >[AS <显示列名 >],[<别名 >.]<选项
>[AS <显示列名 >… ]
FROM <表名 1>[别名 1>][,<表名 2>[别名 2>… ]
其中 ALL表示输出所有记录, 包括重复记录 。
DISTINCT表示输出无重复结果的记录 。 当选择多
个数据库表中的字段时, 可使用别名来区分不同
的表 。 显示列名的作用是在输出结果中, 如果不
希望使用字段名, 可以根据要求设置一个名称 。
选项可以是字段名, 表达式或函数 。 表名代表要
查询的表 。
Visual FoxPro
23
例 列出学生名单 。
OPEN DATABASE D:
SELECT * FROM
命令中的 *表示输出所有字段, 数据来源是学生表,
所有内容以浏览方式显示 。
例 列出所有学生姓名, 去掉重名 。
SELECT DISTINCT 姓名 AS 学生名单 FROM 学生
SELECT 命令中的选项, 不仅可以是字段名, 还可以
是表达式, 也可以是一些函数, SELECT命令可操
纵的函数很多 。
Visual FoxPro
24
例 将所有的学生入学成绩四舍五入, 只显示学号,
姓名和入学成绩 。
SELECT 学号,姓名,ROUND(入学成绩,0) AS ″入学成
绩 ″ FROM
注意:这个结果不影响数据库表中的结果, 只是在输
出时通过函数计算输出 。
例 求出所有学生的入学成绩平均分 。
SELECT AVG(入学成绩 ) AS ″入学成绩平均分 ″
FROM
由以上两例可见, 直接使用 Visual FoxPro提供的各种
SQL函数在输出时进行计算, 便可得到相应的输出
结果 。
Visual FoxPro
25
6.3.2 带条件查询
WHERE是条件语句关键字, 是可选项, 其格式是:
WHERE <条件表达式 >
其中条件表达式可以是单表的条件表达式, 也可以是
多表之间的条件表达式, 表达式用的比较符为,=
( 等于 ), <>,! =( 不等于 ), ==( 精确等于 ),
>( 大于 ), >=( 大于等于 ), <( 小于 ), <=( 小
于等于 ) 。
例 求出湖南学生入学成绩平均分 。
SELECT 籍贯,AVG(入学成绩 ) AS ″入学成绩平均分 ″
FROM 学生 WHERE籍贯 =″湖南 ″
Visual FoxPro
26
条件表达式 是指查询的结果集合应满足的条件, 如果
某行条件为真就包括该行记录 。 下面是可用于条件
表达式中几个特殊运算符的意义和使用方法 。
<字段 > <比较符 > ALL(<子查询 >)
<字段 > <比较符 > ANY( <子查询 >)
<字段 > BETWEEN <范围始值 > AND <范围终值 >
EXISTS(<子查询 >)
<字段 > IN <结果集合 >或者 <字段 > IN (<子查询 >)
<字段 > LIKE <字符表达式 >
<字段 > <比较符 > SOME(<子查询 >)
Visual FoxPro
27
例 列出非湖南籍的学生名单 。
SELECT 学号,姓名,籍贯 FROM 学生 WHERE 籍贯
<>″湖南 ″
SELECT 学号,姓名,籍贯 FROM 学生 WHERE 籍
贯 != ″湖南 ″
或 SELECT 学号,姓名,籍贯 FROM 学生 WHERE
NOT(籍贯 =″湖南 ″)
例 列出江苏籍和贵州籍的学生名单 。
SELECT 学号,姓名,籍贯 FROM 学生 WHERE 籍贯
IN (″江苏 ″,″贵州 ″)
SELECT 学号,姓名,籍贯 FROM 学生 WHERE 籍贯
=″江苏 ″ OR 籍贯 =″贵州 ″
Visual FoxPro
28
例 列出入学成绩在 560分到 650分之间的学生名单 。
SELECT 学号,姓名,入学成绩 FROM 学生 WHERE
入学成绩 BETWEEN 560 AND 650
SELECT 学号,姓名,专业 FROM 学生 WHERE 入学
成绩 >=560 AND 入学成绩 <=650
例 列出所有的姓赵的学生名单 。
SELECT 学号,姓名 FROM 学生 WHERE 姓名 LIKE
″赵 %″
SELECT 学号,姓名,专业 FROM 学生 WHERE 姓名
=″赵 ″
Visual FoxPro
29
例 列出所有成绩为空值的学生学号和课程号 。
SELECT 学号,课程号 FROM 选课 WHERE 成绩 IS
NULL
在以上命令中, 使用了运算符 IS NULL,该运算
符是测试字段值是否为空值, 在查询时用, 字段名
IS [NOT]NULL”的形式, 而不能写成, 字段名
=NULL”或, 字段名 ! =NULL”。
Visual FoxPro
30
6.3.3 嵌套查询
有时候一个 SELECT命令无法完成查询任务,
需要一个子 SELECT的结果作为条件语句的条件,
即需要在一个 SELECT命令的 WHERE子句中出现
另一个 SELECT命令, 这种查询称为嵌套查询 。 通
常把仅嵌入一层子查询的 SELECT命令称为单层嵌
套查询, 把嵌入子查询多于一层的查询称为多层
嵌套查询 。 Visual FoxPro只支持单层嵌套查询 。
Visual FoxPro
31
1,返回单值的子查询
例 列出选修, 数据库原理, 的所有学生的学号 。
SELECT 学号 FROM 选课 WHERE 课程号 =;
(SELECT 课程号 FROM 课程 WHERE 课程名 =″数
据库原理 ″)
上述 SQL语句执行的是两个过程, 首先 在课程表中
找出, 数据库原理, 的课程号 ( 比如, 01001”),
然后 再在选课表中找出课程号等于, 01101”的记
录, 列出这些记录的学号 。
Visual FoxPro
32
2,返回一组值的子查询
若 某 个 子 查 询返 回 值 不止 一 个, 则 必 须 指明 在
WHERE子句中应怎样使用这些返回值 。 通常使用
条件 ANY( 或 SOME), ALL和 IN。
( 1) ANY运算符的用法
例 列出选修, 01101”课的学生中期末成绩比选修
,01102”的最低成绩高的学生的学号和成绩 。
SELECT 学号,成绩 FROM 选课 WHERE 课程号
=″01101″AND成绩 >ANY
(SELECT 成绩 FROM 选课 WHERE 课程号 =″01102″)
该查询必须做 两件事, 先 找出选修, 01102”课的所有
学生的期末成绩 ( 比如说结果为 92和 51), 然后 在
选修, 01101”课的学生中选出其成绩高于选修
,01102”课的任何一个学生的成绩 ( 即高于 72分 )
的那些学生 。
Visual FoxPro
33
( 2) ALL
例 列出选修, 01101”课的学生, 这些学生的成绩比
选修, 01102”课的最高成绩还要高的学生的学号
和成绩 。
SELECT 学号,成绩 FROM 选课 WHERE 课程号
=″01102″ AND成绩 >ALL (SELECT 成绩 FROM
选课 WHERE 课程号 =″01102″)
该查询的 含义是,先找出选修, 01102”课的所有学
生的成绩 ( 比如说结果为 87和 72), 然后再在选
修, 01102”课的学生中选出其成绩中高于选修
,01102”课的所有成绩 ( 即高于 87分 ) 的那些学
生 。
Visual FoxPro
34
( 3) IN
例 列出选修, 数据库原理, 或, 软件工程, 的所有
学生的学号 。
SELECT 学号 FROM 选课 WHERE 课程号 IN;
(SELECT 课程号 FROM 课程 WHERE 课程名 =″数
据库原理 ″OR课程名 =″软件工程 ″)
IN是属于的意思, 等价于, =ANY”,即等于子查询中
任何一个值 。
Visual FoxPro
35
6.3.4 多表查询
在一个表中进行查询, 一般说来是比较简单的,
而在多表之间查询就比较复杂, 必须处理表和表间
的联接关系 。 使用 SELECT命令进行多表查询是很
方便的 。
1,等值联接
等值联接是按对应字段的共同值将一个表中的记录
与另一个表中的记录相联接 。
例 输出所有学生的成绩单, 要求给出学号, 姓名,
课程号, 课程名和成绩 。
SELECT a.学号,a.姓名,b.课程号,c.课程名,b.
FROM 学生 a,选课 b,课程 c;
WHERE a.学号 =b.学号 AND b.课程号 =c.课程号
Visual FoxPro
36
学生成绩查询结果
Visual FoxPro
37
例 列出男生的选课情况, 要求列出学号, 姓名, 课
程号, 课程名, 授课教师和学分数 。
SELECT a.学号,a.姓名 AS 学生姓名,b.课程号,c.课程
名,e.姓名 AS 教师姓名,c.学分 ;
FROM 学生 a,选课 b,课程 c,授课 d,教师 e;
WHERE a.学号 =b.学号 AND b.课程号 =c.课程号 AND
c.课程号 =d.课程号 ;
AND d.教师号 =e.教师号 AND a.性别 =″男 ″
Visual FoxPro
38
男生选课情况查询结果
Visual FoxPro
39
2,非等值联接
例 列出选修, 01102”课的学生中, 期末成绩大于学
号为, 200109”的学生该门课成绩的那些的学号及
其成绩 。
SELECT a.学号,a.成绩 FROM 选课 a,选课 b;
WHERE a.成绩 >b.成绩 AND a.课程号 =b.课程号 AND
b.课程号 =″01102″AND b.学号 =″200109″
Visual FoxPro
40
6.3.5 联接查询
Visual FoxPro 提供的 SELECT 命令, 在
FROM子句中提供一种称之为联接的子句 。 联接
分为内部联接和外部联接 。 外部联接又分为左外
联接, 右外联接和全外联接 。
1,内部联接 ( Inner Join)
实际上, 上面例子全部都是内部联接 。 所谓
内部联接是指包括符合条件的每个表格中的记录 。
也就是说是所有满足联接条件的记录都包含在查
询结果中 。
Visual FoxPro
41
例 列出少数民族学生的学号, 课程号及成绩 。
SELECT a.学号,b.课程号,b.成绩 FROM 学生 a,
选课 b;
WHERE a.学号 =b.学号 AND a.
如果采用内部联接方式,
SELECT a.学号,b.课程号,a.成绩 FROM 学生 a
INNER JOIN 选课 b;
ON a.学号 =b.学号 WHERE a.
所得到的结果完全相同 。
Visual FoxPro
42
2,外部联接 ( Outer Join)
(1)左外联接
也叫左联接 ( Left Outer Join), 其系统执行过
程是左表的某条记录与右表的所有记录依次比较,
若有满足联接条件的, 则产生一个真实值记录 。
若都不满足, 则产生一个含有 NULL值的记录 。
接着, 左表的下一记录与右表的所有记录依次比
较字段值, 重复上述过程, 直到左表所有记录都
比较完为止 。 联接结果的记录个数与左表的记录
个数一致 。
Visual FoxPro
43
( 2)
也叫右联接 ( Right Outer Join), 其系统执
行过程是右表的某条记录与左表的所有记录依
次比较, 若有满足联接条件的, 则产生一个真
实值记录;若都不满足, 则产生一个含有
NULL值的记录 。 接着, 右表的下一记录与左
表的所有记录依次比较字段值, 重复上述过程,
直到左表所有记录都比较完为止 。 联接结果的
记录个数与右表的记录个数一致 。
( 3)
也叫完全联接 ( Full Join), 其系统执行过
程是先按右联接比较字段值, 然后按左联接比
较字段值, 重复记录不记入查询结果中 。
Visual FoxPro
44
6.3.6 查询结果处理
1,排序输出 ( ORDER)
SELECT的查询结果是按查询过程中的自然顺序给出
的, 因此查询结果通常无序, 如果希望查询结果有
序输出, 需要下面的子句配合,ORDER BY <排序
选项 1> [ASC | DESC][,< 排序选项 2>[ASC |
DESC]… ]
其中排序选项可以是字段名, 也可以是数字 。 字段名
必须是主 SELECT子句的选项, 当然是 FROM <表 >
中的字段 。 数字是表的列序号, 第 1列为 1。 ASC指
定的排序项 A按升序排列, DESC指定的排序项按降
序排列 。
Visual FoxPro
45
例 按性别顺序列出学生的学号, 姓名, 性别, 课
程名及成绩, 性别相同的再先按课程后按成绩
由高到低排序 。
SELECT a.学号,a.姓名,a.性别,c.课程名,b.成绩
FROM 学生 a,选课 b,课程 c;
WHERE a.学号 =b.学号 AND b.课程号 =c.课程号
ORDER BY a.性别,c.课程名,b.成绩 DESC
Visual FoxPro
46
查询结果的排序输出
Visual FoxPro
47
2,重定向输出 ( INTO)
INTO是可选项, 表示查询结果可以重定输出方向, 其
[INTO <目标 >] | [TO FILE<文件名 >[ADDITIVE] | TO
PRINTER]
,<目标 >”为有如下 3
ARRAY <数组名 >:将查询结果存到指定数组名的内
存变量数组中 。
CURSOR <临时表 >:将输出结果存到一个临时表 ( 游
标 ), 这个表的操作与其他表一样, 不同的是, 一
旦被关闭就被删除
Visual FoxPro
48
DBF <表 >|TABLE <表 >:将结果存到一个表, 如果该
表 已 经 打 开, 则 系 统 自 动 关 闭 它 。 如果 SET
SAFETY OFF,则重新打开它不提示 。 如果没有指
定后缀, 则默认为,dbf。 在 SELECT命令执行完后,
该表为打开状态 。
,TO FILE <文件名 >[ADDITIVE]”将结果输出到指
定文本文件, ADDITIVE表示将结果添加到文件后
面 。 在输出的文件中, 系统可以自动处理重名的问
题 。 如不同文件同字段名用文件名来区分, 表达式
用 EXP-A,EXP-B等来自动命名, SELECT函数用
函数名来辅助命名 。
,TO PRINTER”将结果送打印机输出 。
Visual FoxPro
49
例 将例 6.25的查询结果保存到 test1.txt文本文件中 。
SELECT a.学号,a.姓名,a.性别,c.课程名,b.成绩 FROM
学生 a,选课 b,课程 c;
WHERE a.学号 =b.学号 AND b.课程号 =c.课程号
ORDER BY a.性别,c.课程名,b.成绩 DESC TO FILE
test1
test1.txt文件中的内容参见图 6.5,但文件格式为文本
文件 。
Visual FoxPro
50
例 查询学生所学课程和成绩, 输出学号, 姓名,
课程名和成绩, 并将查询结果存入 testtable表中 。
SELECT a.学号,a.姓名,b.课程名,b.成绩 FROM 学
生 a,成绩 b;
WHERE a.学号 =b.学号 INTO CURSOR test
SELECT a.学号,a.姓名,b.课程名,a.成绩 FROM test
a,课程 b;
WHERE a,课 程 号 =b,课程号 INTO TABLE
testtable ORDER BY a.学号
Visual FoxPro
51
3,输出合并 ( UNION)
输出合并是指将两个查询结果进行集合并操作, 其子
[UNION [ALL] <SELECT命令 >]
其中 ALL表示结果全部合并 。 若没有 ALL,则重复的
记录将被自动取掉 。
( 1) 不能合并子查询的结果 。
( 2) 两个 SELECT命令必须输出同样的列数 。
( 3) 两个表各相应列出的数据类型必须相同, 数字
和字符不能合并 。
( 4) 仅最后一个 <SELECT命令 >中可以用 ORDER
BY子句, 且排序选项必须用数字说明 。
Visual FoxPro
52
例 列出选修, 01101”或, 01102”课程的所有学生
的学号 。
SELECT 学号 FROM 成绩 WHERE 课程号
=″01101″UNION SELECT 学号 FROM;
成绩 WHERE 课程号 =″01102″
Visual FoxPro
53
4,分组统计 ( GROUP) 与筛选 ( HAVING)
查询结果可以分组,
GROUP BY <分组选项 1>[,<分组选项 2>… ]
其中 <分组选项 >可以是字段名, SQL函数表达式,
也可以是列序号 ( 最左边为 1) 。
HAVING <筛选条件表达式 >
HAVING子句与 WHERE功能一样, 只不过是与
GROUP BY子句连用, 用来指定每一分组内应满
足的条件 。
Visual FoxPro
54
例 分别统计男女人数 。
SELECT 性别,COUNT(性别 ) FROM 学生 GROUP
BY
例 分别统计男女中少数民族学生人数 。
SELECT 性别,COUNT(性别 ) FROM 学生 GROUP
BY 性别 WHERE
如果把命令写成如下形式, 统计的结果就是错误的 。
SELECT 性别,COUNT(性别 ) FROM 学生 ;
GROUP BY 性别 HAVING
Visual FoxPro
55
6.4.1 插入记录
Visual FoxPro支持两种 SQL插入命令,
格式 1:
INSERT INTO <表名 >[(字段名 1[<字段名 2>[,… ]])]
VALUES(<表达式 1>[,<表达式 2>[,… ]])
该命 令在指定的 表尾添加一 条新记录, 其值为
VALUES后面表达式的值 。
当需要插入表中所有字段的数据时, 表名后面的
字段名可以缺省, 但插入数据的格式及顺序必须与
表的结构完全吻合;若只需要插入表中某些字段的
数据, 就需要列出插入数据的字段名, 当然相应表
达式的数据位置应与之对应 。
6.4 数据操纵
Visual FoxPro
56
例 向学生表中添加记录 。
INSERT INTO 学生 VALUES(″231002″,″阳雨光 ″,″男″,{^1988-09-10},.T.,″上海 ″,610,″″,″″)
INSERT INTO 学生 (学号,姓名 ) VALUES(″231109″,″
李成功 ″)
格式 2:
INSERT INTO <表名 > FROM ARRAY <数组名 >|FROM MEMVAR]
该命令在指定的表尾添加一条新记录, 其值来自
于数组或对应的同名内存变量 。
例 已经定义了数组 A( 5), A中各元素的值分别是:
AA( 1) =″231013″,A( 2) =″张阳 ″,A( 3) =″女″,A( 4) ={^1988-09-10},A( 5) =.T.。 利用该数
组向学生表中添加记录 。
INSERT INTO 学生 FROM ARRAY A
Visual FoxPro
57
6.4.2 删除记录
在 Visual FoxPro中, DELETE可以为指定的数据表中
的记录加删除标记 。
DELETE FROM [<数据库名 >!] <表名 > [WHERE <
条件表达式 >
该命令从指定表中, 根据指定的条件逻辑删除记录 。
例 将, 学生, 表所有男生的记录逻辑删除 。
DELETE FROM 学生 WHERE 性别 =″男 ″
完成以上操作后, 在学生表将所有男生的记录逻辑删
除了, 但没有从物理上删除 。 只有执行了 PACK命
令, 逻辑删除的记录才真正地从物理上删除 。 逻辑
删除的记录还可以用 RECALL命令取消删除 。
Visual FoxPro
58
在逻辑删除记录时, 若在当前工作区中没有表
被打开时, 该命令执行后将在当前工作区打开该
命令指定的表;若当前工作区打开的是其他表,
则该命令执行后将在一个新的工作区中打开, 逻
辑删除完成后, 仍保持原当前工作区 。 若指定的
表在非当前工作区中打开, 逻辑删除完成后, 指
定的表仍在原工作区中打开, 且仍保持原当前工
作区 。
Visual FoxPro
59
6.4.3 更新记录
更新记录时对存储在表中的记录进行修改, 命令是
UPDATE,也可以对用 SELECT语句选择出的记录
进行数据更新 。
UPDATE [<数据库名 >!]<表名 >
SET<字段名 1>=<表达式 1>[,<字段名 2>=<表达式 2>… ]
[WHERE<逻辑表达式 >]
该命令用指定的新值更新记录 。
Visual FoxPro
60
例 将, 学生, 表中胡敏杰学生的籍贯改为广东 。
UPDATE 学生 SET 籍贯 =′广东 ′ WHERE 姓名 =′胡
敏杰 ′
例 所有男生的各科成绩加 20
UPDATE 选课 SET 成绩 =成绩 +20
WHERE学号 IN( SELECT 学号 FROM 学生
WHERE 性别 =′男 ′)
以上命令中, 用到了 WHERE条件运算符, IN”
和对用 SELECT语句选择出的记录进行数据更新 。
注意 UPDATE一次只能在单一的表中更新记录 。
1
i s u a l
F
V
o x P r o
Visual FoxPro
2
6.1 SQL语言概述
6.2 数据定义
6.3 数据查询
6.4 数据操纵
Visual FoxPro
3
20世纪 80年代初, 美国国家标准协会 ( ANSI) 开
始着手制定 SQL标准, 最早的 ANSI标准于 1986年完
成, 它也被叫做 SQL86。 SQL标准的出台使 SQL作
为标准关系数据库语言的地位得到了加强 。 随后,
SQL标准几经修改和完善, 其间经历了 SQL89、
SQL92,一直到最近的 SQL99等多个版本, 每个新
版本都较前面的版本有重大改进, SQL99更是包含
了对诸如面向对象, 递归, 触发器等概念的支持 。
目前, 各主流数据库产品采用的 SQL标准是 1992年
制定的 SQL92。
6.1 SQL语言概述
Visual FoxPro
4
按照 ANSI的规定, SQL被作为关系数据库的标
准语言 。 SQL语句可以用来执行各种各样的操作 。
目前流行的关系数据库管理系统, 如 Qracle,Sybase、
SQL Server,Visual FoxPro等都采用了 SQL语言标
准, 而且很多数据库都对 SQL语句进行了再开发和
扩展 。
SQL语言 具有如下 特点:
( 1) SQL是一种一体化的语言 。 尽管设计 SQL的最初
目的是查询, 数据查询也是其最重要的功能之一,
但 SQL决不仅仅是一个查询工具, 它集数据定义,
数据查询, 数据操纵和数据控制功能于一体, 可以
独立完成数据库的全部操作 。
( 2) SQL语言是一种高度非过程化的语言 。 它没有必
要一步步地告诉计算机, 如何, 去做, 而只需要描
述清楚用户要, 做什么,, SQL语言就可以将要求
交给系统, 自动完成全部工作 。
Visual FoxPro
5
( 3) SQL语言非常简洁 。 虽然 SQL语言功能很强,
但 它只有为 数不多的 9 条命 令,CREATE,
DROP, ALTER, SELECT, INSERT,
UPDATE,DELETE,GRANT,REVOKE。 另
外 SQL的语法也非常简单, 它很接近英语自然语
言, 因此容易学习和掌握 。
( 4) SQL语言可以直接以命令方式交互使用, 也
可以嵌入到程序设计语言中以程序方式使用 。 现
在很多数据库应用开发工具都将 SQL语言直接融
入到自身的语言之中, 使用起来更方便, Visual
FoxPro就是如此 。 这些使用方式为用户提供了灵
活的选择余地 。 此外, 尽管 SQL的使用方式不同,
但 SQL语言的语法基本是一致的 。
Visual FoxPro
6
Visual FoxPro在 SQL方面支持 数据定义, 数
据查询和数据操纵功能, 但在具体实现方面也
存在一些差异 。 另外, 由于 Visual FoxPro自身
在安全控制方面的缺陷, 所以它没有提供数据
控制功能 。
SQL虽然在各种数据库产品中得到了广泛的
支持, 但迄今为止, 它只是一种建议标准, 各
种数据库产品中所实现的 SQL在语法, 功能等
方面均略有差异, 本章讲述 Visual FoxPro 中
SQL的语法, 功能与应用 。
Visual FoxPro
7
6.2.1 建立表结构
CREATE TABLE|DBF < 表名 1> [NAME < 长表名>][FREE]
(<字段名 1> <类型 >(<宽度 >[,<小数位数 >])[NULL|NOT
NULL]
[CHECK <条件表达式 1>[ERROR<出错显示信息 >]]
[DEFAULT < 表达式 1>][PRIMARY KEY |UNIQUE]REFERENCES <表名 2>[TAG <标识 1>]
[<字段名 2><类型 >(<宽度 >[,<小数位数 >])[NULL|NOT
NULL]
[CHECK <条件表达式 2>[ERROR<出错显示信息 >]]
[DEFAULT < 表达式 2>][PRIMARY KEY |UNIQUE]REFERENCES<表名 3>[TAG<标识 2>]
…… )|FROM ARRAY <数组名 >
6.2 数据定义
Visual FoxPro
8
表名 1,要建立的表的名称 。
FREE,如果当前已经打开一个数据库, 这里所建立
的新表会自动加入该数据库, 除非使用参数
,FREE”说明该新表作为一个自由表不加入当前
数据库 。 如果没有打开的数据库, 该参数无意义 。
字段名 1,字段名 2,……, 所要建立的新表的字段
名, 在语法格式中, 两个字段名之间的语法成分
都是对一个字段的属性说明, 包括:
类型 —— 说明字段类型 。
宽度及小数位数 —— 字段宽度及小数位数 。
NULL,NOT NULL—— 该字段是否允许, 空值,,
其默认值为 NULL,即允许, 空, 值 。
CHECK 条件表达式 —— 用来检测字段的值是否有效,
这是实行数据库的一种完整性检查 。
Visual FoxPro
9
ERROR 出错显示信息 —— 当完整性检查有错误, 即
条件表达式的值为假时的提示信息 。 应当注意, 当
为一个表的某个字段建立了实行完整性检测的条件
表达式后, 在对该数据表输入数据时, 系统会自动
检测所输入的字段值是否使条件表达式为假, 当有
一个数据使其为假时, 系统自动显示这里所提示的
出错信息 。
DEFAULT 表达式 —— 为一个字段指定的默认值 。
PRIMARY KEY—— 指定该字段为关键字段, 非数据
库表不能使用该参数 。
UNIQUE—— 指定该字段为一个侯选关键字段 。 注意,
指定为关键或侯选关键的字段都不允许出现重复值,
这称为对字段值的唯一性约束 。
Visual FoxPro
10
REFERENCES 表名 —— 这里指定的表作为新建表的
永久性父表, 新建表作为子表 。
TAG 标识 —— 父表中的关联字段, 若缺省该参数, 则
默认父表的主索引字段作为关联字段 。
数组名 —— 用指定数组的值建立输入表 。
从以上命令格式可以看出, 用 CREATE TABLE命令
建立表可以完成用表设计器完成的所有功能 。 除了
建立表的基本功能外, 它还包括满足实体完整性的
主关键字 ( 主索引 ) PRIMARY KEY,定义域完整
性的 CHECK约束及出错提示信息 ERROR,定义默
认值的 DEFAULT等 。 另外还有描述表之间联系的
FOREIGN KEY和 REFERENCES等 。
Visual FoxPro
11
例 利用 SQL命令建立学生管理数据库, 其中包含 3个
表:学生表, 选课表和课程表 。
( 1) 用 CREATE命令建立数据库 。
CREATE DATABASE D:
( 2) 用 CREATE命令建立学生表 。
CREATE TABLE 学生 (学号 C(5) PRIMARY KEY,姓
名 C(8),;
入学成绩 N(5,1) CHECK(入学成绩 >0) ERROR ″成绩
应该大于 0! ″)
Visual FoxPro
12
( 3) 建立课程表 。
CREATE TABLE 课程 (课程号 C(5) PRIMARY KEY,课
程名 C(20),学分 N(1))
( 4) 建立选课表 。
CREATE TABLE 选课 (学号 C( 5), 课程号 C(5),;
成绩 I CHECK(成绩 >=0 AND 成绩 <=100);
ERROR″成绩值的范围 0~100! ″DEFAULT 60,;
FOREIGN KEY 学号 TAG 学号 REFERENCES 学生, ;
FOREIGN KEY 课程号 TAG 课程号 REFERENCES 课
程
Visual FoxPro
13
利用 SQL命令建立数据库
Visual FoxPro
14
用 SQL CREATE命令新建的表自动在最小可用
工作区打开, 并可以通过别名引用, 新表的打开方
式为独占方式, 忽略 SET EXCLUSIVE的当前设置 。
如果建立自由表 ( 当前没有打开的数据库或使用
了 FREE), 则很多选项在命令中不能使用, 如
NAME,CHECK,DEFAULT,FOREIGN KEY、
PRIMARY KEY和 REFERENCES等 。
注意
Visual FoxPro
15
6.2.2 删除表
删除表的 SQL
DROP TABLE <表名 >
DROP TABLE命令直接从磁盘上删除所指定的表文
件 。 如果指定的表文件是数据库中的表并且相应
的数据库是当前数据库, 则从数据库中删除了表 。
否则虽然从磁盘上删除了表文件, 但是记录在数
据库文件中的信息却没有删除, 此后会出现错误
提示 。 所以要删除数据库中的表时, 最好应使数
据库是当前打开的数据库, 在数据库中进行操作 。
Visual FoxPro
16
6.2.3 修改表结构
修改表结构的命令是 ALTER TABLE,该命令有
3种格式 。
格式 1:
ALTER TABLE <表名 1>
ADD|ALTER [COLUMN] <字段名 ><字段类型 >[(<宽
度 >[,<小数位数 >])]
[NULL | NOT NULL][CHECK < 逻辑表达式 >
[ERROR<出错显示信息 >]]
[DEFAULT <表达式 >][PRIMARY KEY|UNIQUE]
[REFERENCES <表名 2>[TAG <标识名 >]]
例 为课程表增加一个整数类型的学时字段 。
ALTER TABLE 课程 ;
ADD 学时 I CHECK(学时 >16) ERROR ″学时应该大
于 16! ″
Visual FoxPro
17
格式 2:
ALTER TABLE <表名 >
ALTER [COLUMN] <字段名 > [NULL|NOT NULL]
[SET DEFAULT <表达式 >[SET CHECK <逻辑表达
式 > [ERROR <出错显示信息 >]]
[DROP DEFAULT][DROP CHECK]
该格式命令主要用于定义, 修改和删除有效性规则以
及默认值定义 。
例 删除学时字段的有效性规则 。
ALTER TABLE 课程 ALTER 学时 DROP CHECK
Visual FoxPro
18
格式 3:
ALTER TABLE <表名 > [DROP [COLUMN] <字段 >
[SET CHECK<逻辑表达式 >[ERROR <出错显示信息 >
[DROP CHECK]
[ADD PRIMARY KEY <表达式 > TAG <索引标识 >
[FOR <逻辑表达式 >]]
[DROP PRIMARY KEY]
[ADD UNIQUE <表达式 > [TAG <索引标识 > [FOR <逻
辑表达式 >]
[DROP UNIQUE TAG <索引标识 >
[ADD FOREIGN KEY <表达式 > TAG <索引标识 >
[FOR <逻辑表达式 >]]
Visual FoxPro
19
REFERENCES <表名 2>[TAG <索引标识 >]]
[DROP FOREIGN KEY TAG <索引标识 >[SAVE]]
[RENAME COLUMN <原字段名 > TO <目标字段名 >]
该 格 式 的 命 令 可 以 删 除 指 定 字 段 ( DROP
[COLUMN]), 修改字段名 (RENAME COLUMN)、
修改指定表的完整性规则, 包括主索引, 外关键字,
候选索引及表的合法值限定的添加与删除 。
例 删除课程表中的学时字段 。
ALTER TABLE 课程 DROP COLUMN 学时
Visual FoxPro
20
Visual FoxPro的 SQL SELECT命令的语法格式是,
SELECT [ALL|DISTINCT]
[<别名 >.]<选项 >[AS <显示列名 >][,[<别名 >.]<选项
>[AS <显示列名 >]… ]
FROM [<数据库名 !]<表名 >[[AS] <本地别名 >]
[[INNER | LEFT [OUTER] |
RIGHT[OUTER]|FULL [OUTER]
JOIN <数据库名 >!]<表名 >[[AS]<本地别名 >][ON <
联接条件 >… ]
[[INTO <目标 >|[TO FILE<文件名 >][ADDITIVE]
|TO PRINTER [PROMPT]|TO SCREEN]]
6.3 数据查询
Visual FoxPro
21
[PREFERENCE<参照名
>][NOCONSOLE][PLAIN][NOWAIT]
[WHERE <联接条件 1>[AND <联接条件 2>… ]
[AND|OR <过滤条件 1>[AND|OR <过滤条件 2>… ]]]
[GROUP BY < 分组列名 1>[,< 分组列名
2>… ]][HAVING <过滤条件 >]
[UNION[ALL]SELECT命令 ]
[ORDER BY <排序选项 1>[ASC|DESC][,<排序选项
2>[ASC|DESC]… ]]
Visual FoxPro
22
6.3.1 基本查询
所谓基本查询是指无条件查询, 其格式是:
SELECT [ALL|DISTINCT]
[<别名 >.]<选项 >[AS <显示列名 >],[<别名 >.]<选项
>[AS <显示列名 >… ]
FROM <表名 1>[别名 1>][,<表名 2>[别名 2>… ]
其中 ALL表示输出所有记录, 包括重复记录 。
DISTINCT表示输出无重复结果的记录 。 当选择多
个数据库表中的字段时, 可使用别名来区分不同
的表 。 显示列名的作用是在输出结果中, 如果不
希望使用字段名, 可以根据要求设置一个名称 。
选项可以是字段名, 表达式或函数 。 表名代表要
查询的表 。
Visual FoxPro
23
例 列出学生名单 。
OPEN DATABASE D:
SELECT * FROM
命令中的 *表示输出所有字段, 数据来源是学生表,
所有内容以浏览方式显示 。
例 列出所有学生姓名, 去掉重名 。
SELECT DISTINCT 姓名 AS 学生名单 FROM 学生
SELECT 命令中的选项, 不仅可以是字段名, 还可以
是表达式, 也可以是一些函数, SELECT命令可操
纵的函数很多 。
Visual FoxPro
24
例 将所有的学生入学成绩四舍五入, 只显示学号,
姓名和入学成绩 。
SELECT 学号,姓名,ROUND(入学成绩,0) AS ″入学成
绩 ″ FROM
注意:这个结果不影响数据库表中的结果, 只是在输
出时通过函数计算输出 。
例 求出所有学生的入学成绩平均分 。
SELECT AVG(入学成绩 ) AS ″入学成绩平均分 ″
FROM
由以上两例可见, 直接使用 Visual FoxPro提供的各种
SQL函数在输出时进行计算, 便可得到相应的输出
结果 。
Visual FoxPro
25
6.3.2 带条件查询
WHERE是条件语句关键字, 是可选项, 其格式是:
WHERE <条件表达式 >
其中条件表达式可以是单表的条件表达式, 也可以是
多表之间的条件表达式, 表达式用的比较符为,=
( 等于 ), <>,! =( 不等于 ), ==( 精确等于 ),
>( 大于 ), >=( 大于等于 ), <( 小于 ), <=( 小
于等于 ) 。
例 求出湖南学生入学成绩平均分 。
SELECT 籍贯,AVG(入学成绩 ) AS ″入学成绩平均分 ″
FROM 学生 WHERE籍贯 =″湖南 ″
Visual FoxPro
26
条件表达式 是指查询的结果集合应满足的条件, 如果
某行条件为真就包括该行记录 。 下面是可用于条件
表达式中几个特殊运算符的意义和使用方法 。
<字段 > <比较符 > ALL(<子查询 >)
<字段 > <比较符 > ANY( <子查询 >)
<字段 > BETWEEN <范围始值 > AND <范围终值 >
EXISTS(<子查询 >)
<字段 > IN <结果集合 >或者 <字段 > IN (<子查询 >)
<字段 > LIKE <字符表达式 >
<字段 > <比较符 > SOME(<子查询 >)
Visual FoxPro
27
例 列出非湖南籍的学生名单 。
SELECT 学号,姓名,籍贯 FROM 学生 WHERE 籍贯
<>″湖南 ″
SELECT 学号,姓名,籍贯 FROM 学生 WHERE 籍
贯 != ″湖南 ″
或 SELECT 学号,姓名,籍贯 FROM 学生 WHERE
NOT(籍贯 =″湖南 ″)
例 列出江苏籍和贵州籍的学生名单 。
SELECT 学号,姓名,籍贯 FROM 学生 WHERE 籍贯
IN (″江苏 ″,″贵州 ″)
SELECT 学号,姓名,籍贯 FROM 学生 WHERE 籍贯
=″江苏 ″ OR 籍贯 =″贵州 ″
Visual FoxPro
28
例 列出入学成绩在 560分到 650分之间的学生名单 。
SELECT 学号,姓名,入学成绩 FROM 学生 WHERE
入学成绩 BETWEEN 560 AND 650
SELECT 学号,姓名,专业 FROM 学生 WHERE 入学
成绩 >=560 AND 入学成绩 <=650
例 列出所有的姓赵的学生名单 。
SELECT 学号,姓名 FROM 学生 WHERE 姓名 LIKE
″赵 %″
SELECT 学号,姓名,专业 FROM 学生 WHERE 姓名
=″赵 ″
Visual FoxPro
29
例 列出所有成绩为空值的学生学号和课程号 。
SELECT 学号,课程号 FROM 选课 WHERE 成绩 IS
NULL
在以上命令中, 使用了运算符 IS NULL,该运算
符是测试字段值是否为空值, 在查询时用, 字段名
IS [NOT]NULL”的形式, 而不能写成, 字段名
=NULL”或, 字段名 ! =NULL”。
Visual FoxPro
30
6.3.3 嵌套查询
有时候一个 SELECT命令无法完成查询任务,
需要一个子 SELECT的结果作为条件语句的条件,
即需要在一个 SELECT命令的 WHERE子句中出现
另一个 SELECT命令, 这种查询称为嵌套查询 。 通
常把仅嵌入一层子查询的 SELECT命令称为单层嵌
套查询, 把嵌入子查询多于一层的查询称为多层
嵌套查询 。 Visual FoxPro只支持单层嵌套查询 。
Visual FoxPro
31
1,返回单值的子查询
例 列出选修, 数据库原理, 的所有学生的学号 。
SELECT 学号 FROM 选课 WHERE 课程号 =;
(SELECT 课程号 FROM 课程 WHERE 课程名 =″数
据库原理 ″)
上述 SQL语句执行的是两个过程, 首先 在课程表中
找出, 数据库原理, 的课程号 ( 比如, 01001”),
然后 再在选课表中找出课程号等于, 01101”的记
录, 列出这些记录的学号 。
Visual FoxPro
32
2,返回一组值的子查询
若 某 个 子 查 询返 回 值 不止 一 个, 则 必 须 指明 在
WHERE子句中应怎样使用这些返回值 。 通常使用
条件 ANY( 或 SOME), ALL和 IN。
( 1) ANY运算符的用法
例 列出选修, 01101”课的学生中期末成绩比选修
,01102”的最低成绩高的学生的学号和成绩 。
SELECT 学号,成绩 FROM 选课 WHERE 课程号
=″01101″AND成绩 >ANY
(SELECT 成绩 FROM 选课 WHERE 课程号 =″01102″)
该查询必须做 两件事, 先 找出选修, 01102”课的所有
学生的期末成绩 ( 比如说结果为 92和 51), 然后 在
选修, 01101”课的学生中选出其成绩高于选修
,01102”课的任何一个学生的成绩 ( 即高于 72分 )
的那些学生 。
Visual FoxPro
33
( 2) ALL
例 列出选修, 01101”课的学生, 这些学生的成绩比
选修, 01102”课的最高成绩还要高的学生的学号
和成绩 。
SELECT 学号,成绩 FROM 选课 WHERE 课程号
=″01102″ AND成绩 >ALL (SELECT 成绩 FROM
选课 WHERE 课程号 =″01102″)
该查询的 含义是,先找出选修, 01102”课的所有学
生的成绩 ( 比如说结果为 87和 72), 然后再在选
修, 01102”课的学生中选出其成绩中高于选修
,01102”课的所有成绩 ( 即高于 87分 ) 的那些学
生 。
Visual FoxPro
34
( 3) IN
例 列出选修, 数据库原理, 或, 软件工程, 的所有
学生的学号 。
SELECT 学号 FROM 选课 WHERE 课程号 IN;
(SELECT 课程号 FROM 课程 WHERE 课程名 =″数
据库原理 ″OR课程名 =″软件工程 ″)
IN是属于的意思, 等价于, =ANY”,即等于子查询中
任何一个值 。
Visual FoxPro
35
6.3.4 多表查询
在一个表中进行查询, 一般说来是比较简单的,
而在多表之间查询就比较复杂, 必须处理表和表间
的联接关系 。 使用 SELECT命令进行多表查询是很
方便的 。
1,等值联接
等值联接是按对应字段的共同值将一个表中的记录
与另一个表中的记录相联接 。
例 输出所有学生的成绩单, 要求给出学号, 姓名,
课程号, 课程名和成绩 。
SELECT a.学号,a.姓名,b.课程号,c.课程名,b.
FROM 学生 a,选课 b,课程 c;
WHERE a.学号 =b.学号 AND b.课程号 =c.课程号
Visual FoxPro
36
学生成绩查询结果
Visual FoxPro
37
例 列出男生的选课情况, 要求列出学号, 姓名, 课
程号, 课程名, 授课教师和学分数 。
SELECT a.学号,a.姓名 AS 学生姓名,b.课程号,c.课程
名,e.姓名 AS 教师姓名,c.学分 ;
FROM 学生 a,选课 b,课程 c,授课 d,教师 e;
WHERE a.学号 =b.学号 AND b.课程号 =c.课程号 AND
c.课程号 =d.课程号 ;
AND d.教师号 =e.教师号 AND a.性别 =″男 ″
Visual FoxPro
38
男生选课情况查询结果
Visual FoxPro
39
2,非等值联接
例 列出选修, 01102”课的学生中, 期末成绩大于学
号为, 200109”的学生该门课成绩的那些的学号及
其成绩 。
SELECT a.学号,a.成绩 FROM 选课 a,选课 b;
WHERE a.成绩 >b.成绩 AND a.课程号 =b.课程号 AND
b.课程号 =″01102″AND b.学号 =″200109″
Visual FoxPro
40
6.3.5 联接查询
Visual FoxPro 提供的 SELECT 命令, 在
FROM子句中提供一种称之为联接的子句 。 联接
分为内部联接和外部联接 。 外部联接又分为左外
联接, 右外联接和全外联接 。
1,内部联接 ( Inner Join)
实际上, 上面例子全部都是内部联接 。 所谓
内部联接是指包括符合条件的每个表格中的记录 。
也就是说是所有满足联接条件的记录都包含在查
询结果中 。
Visual FoxPro
41
例 列出少数民族学生的学号, 课程号及成绩 。
SELECT a.学号,b.课程号,b.成绩 FROM 学生 a,
选课 b;
WHERE a.学号 =b.学号 AND a.
如果采用内部联接方式,
SELECT a.学号,b.课程号,a.成绩 FROM 学生 a
INNER JOIN 选课 b;
ON a.学号 =b.学号 WHERE a.
所得到的结果完全相同 。
Visual FoxPro
42
2,外部联接 ( Outer Join)
(1)左外联接
也叫左联接 ( Left Outer Join), 其系统执行过
程是左表的某条记录与右表的所有记录依次比较,
若有满足联接条件的, 则产生一个真实值记录 。
若都不满足, 则产生一个含有 NULL值的记录 。
接着, 左表的下一记录与右表的所有记录依次比
较字段值, 重复上述过程, 直到左表所有记录都
比较完为止 。 联接结果的记录个数与左表的记录
个数一致 。
Visual FoxPro
43
( 2)
也叫右联接 ( Right Outer Join), 其系统执
行过程是右表的某条记录与左表的所有记录依
次比较, 若有满足联接条件的, 则产生一个真
实值记录;若都不满足, 则产生一个含有
NULL值的记录 。 接着, 右表的下一记录与左
表的所有记录依次比较字段值, 重复上述过程,
直到左表所有记录都比较完为止 。 联接结果的
记录个数与右表的记录个数一致 。
( 3)
也叫完全联接 ( Full Join), 其系统执行过
程是先按右联接比较字段值, 然后按左联接比
较字段值, 重复记录不记入查询结果中 。
Visual FoxPro
44
6.3.6 查询结果处理
1,排序输出 ( ORDER)
SELECT的查询结果是按查询过程中的自然顺序给出
的, 因此查询结果通常无序, 如果希望查询结果有
序输出, 需要下面的子句配合,ORDER BY <排序
选项 1> [ASC | DESC][,< 排序选项 2>[ASC |
DESC]… ]
其中排序选项可以是字段名, 也可以是数字 。 字段名
必须是主 SELECT子句的选项, 当然是 FROM <表 >
中的字段 。 数字是表的列序号, 第 1列为 1。 ASC指
定的排序项 A按升序排列, DESC指定的排序项按降
序排列 。
Visual FoxPro
45
例 按性别顺序列出学生的学号, 姓名, 性别, 课
程名及成绩, 性别相同的再先按课程后按成绩
由高到低排序 。
SELECT a.学号,a.姓名,a.性别,c.课程名,b.成绩
FROM 学生 a,选课 b,课程 c;
WHERE a.学号 =b.学号 AND b.课程号 =c.课程号
ORDER BY a.性别,c.课程名,b.成绩 DESC
Visual FoxPro
46
查询结果的排序输出
Visual FoxPro
47
2,重定向输出 ( INTO)
INTO是可选项, 表示查询结果可以重定输出方向, 其
[INTO <目标 >] | [TO FILE<文件名 >[ADDITIVE] | TO
PRINTER]
,<目标 >”为有如下 3
ARRAY <数组名 >:将查询结果存到指定数组名的内
存变量数组中 。
CURSOR <临时表 >:将输出结果存到一个临时表 ( 游
标 ), 这个表的操作与其他表一样, 不同的是, 一
旦被关闭就被删除
Visual FoxPro
48
DBF <表 >|TABLE <表 >:将结果存到一个表, 如果该
表 已 经 打 开, 则 系 统 自 动 关 闭 它 。 如果 SET
SAFETY OFF,则重新打开它不提示 。 如果没有指
定后缀, 则默认为,dbf。 在 SELECT命令执行完后,
该表为打开状态 。
,TO FILE <文件名 >[ADDITIVE]”将结果输出到指
定文本文件, ADDITIVE表示将结果添加到文件后
面 。 在输出的文件中, 系统可以自动处理重名的问
题 。 如不同文件同字段名用文件名来区分, 表达式
用 EXP-A,EXP-B等来自动命名, SELECT函数用
函数名来辅助命名 。
,TO PRINTER”将结果送打印机输出 。
Visual FoxPro
49
例 将例 6.25的查询结果保存到 test1.txt文本文件中 。
SELECT a.学号,a.姓名,a.性别,c.课程名,b.成绩 FROM
学生 a,选课 b,课程 c;
WHERE a.学号 =b.学号 AND b.课程号 =c.课程号
ORDER BY a.性别,c.课程名,b.成绩 DESC TO FILE
test1
test1.txt文件中的内容参见图 6.5,但文件格式为文本
文件 。
Visual FoxPro
50
例 查询学生所学课程和成绩, 输出学号, 姓名,
课程名和成绩, 并将查询结果存入 testtable表中 。
SELECT a.学号,a.姓名,b.课程名,b.成绩 FROM 学
生 a,成绩 b;
WHERE a.学号 =b.学号 INTO CURSOR test
SELECT a.学号,a.姓名,b.课程名,a.成绩 FROM test
a,课程 b;
WHERE a,课 程 号 =b,课程号 INTO TABLE
testtable ORDER BY a.学号
Visual FoxPro
51
3,输出合并 ( UNION)
输出合并是指将两个查询结果进行集合并操作, 其子
[UNION [ALL] <SELECT命令 >]
其中 ALL表示结果全部合并 。 若没有 ALL,则重复的
记录将被自动取掉 。
( 1) 不能合并子查询的结果 。
( 2) 两个 SELECT命令必须输出同样的列数 。
( 3) 两个表各相应列出的数据类型必须相同, 数字
和字符不能合并 。
( 4) 仅最后一个 <SELECT命令 >中可以用 ORDER
BY子句, 且排序选项必须用数字说明 。
Visual FoxPro
52
例 列出选修, 01101”或, 01102”课程的所有学生
的学号 。
SELECT 学号 FROM 成绩 WHERE 课程号
=″01101″UNION SELECT 学号 FROM;
成绩 WHERE 课程号 =″01102″
Visual FoxPro
53
4,分组统计 ( GROUP) 与筛选 ( HAVING)
查询结果可以分组,
GROUP BY <分组选项 1>[,<分组选项 2>… ]
其中 <分组选项 >可以是字段名, SQL函数表达式,
也可以是列序号 ( 最左边为 1) 。
HAVING <筛选条件表达式 >
HAVING子句与 WHERE功能一样, 只不过是与
GROUP BY子句连用, 用来指定每一分组内应满
足的条件 。
Visual FoxPro
54
例 分别统计男女人数 。
SELECT 性别,COUNT(性别 ) FROM 学生 GROUP
BY
例 分别统计男女中少数民族学生人数 。
SELECT 性别,COUNT(性别 ) FROM 学生 GROUP
BY 性别 WHERE
如果把命令写成如下形式, 统计的结果就是错误的 。
SELECT 性别,COUNT(性别 ) FROM 学生 ;
GROUP BY 性别 HAVING
Visual FoxPro
55
6.4.1 插入记录
Visual FoxPro支持两种 SQL插入命令,
格式 1:
INSERT INTO <表名 >[(字段名 1[<字段名 2>[,… ]])]
VALUES(<表达式 1>[,<表达式 2>[,… ]])
该命 令在指定的 表尾添加一 条新记录, 其值为
VALUES后面表达式的值 。
当需要插入表中所有字段的数据时, 表名后面的
字段名可以缺省, 但插入数据的格式及顺序必须与
表的结构完全吻合;若只需要插入表中某些字段的
数据, 就需要列出插入数据的字段名, 当然相应表
达式的数据位置应与之对应 。
6.4 数据操纵
Visual FoxPro
56
例 向学生表中添加记录 。
INSERT INTO 学生 VALUES(″231002″,″阳雨光 ″,″男″,{^1988-09-10},.T.,″上海 ″,610,″″,″″)
INSERT INTO 学生 (学号,姓名 ) VALUES(″231109″,″
李成功 ″)
格式 2:
INSERT INTO <表名 > FROM ARRAY <数组名 >|FROM MEMVAR]
该命令在指定的表尾添加一条新记录, 其值来自
于数组或对应的同名内存变量 。
例 已经定义了数组 A( 5), A中各元素的值分别是:
AA( 1) =″231013″,A( 2) =″张阳 ″,A( 3) =″女″,A( 4) ={^1988-09-10},A( 5) =.T.。 利用该数
组向学生表中添加记录 。
INSERT INTO 学生 FROM ARRAY A
Visual FoxPro
57
6.4.2 删除记录
在 Visual FoxPro中, DELETE可以为指定的数据表中
的记录加删除标记 。
DELETE FROM [<数据库名 >!] <表名 > [WHERE <
条件表达式 >
该命令从指定表中, 根据指定的条件逻辑删除记录 。
例 将, 学生, 表所有男生的记录逻辑删除 。
DELETE FROM 学生 WHERE 性别 =″男 ″
完成以上操作后, 在学生表将所有男生的记录逻辑删
除了, 但没有从物理上删除 。 只有执行了 PACK命
令, 逻辑删除的记录才真正地从物理上删除 。 逻辑
删除的记录还可以用 RECALL命令取消删除 。
Visual FoxPro
58
在逻辑删除记录时, 若在当前工作区中没有表
被打开时, 该命令执行后将在当前工作区打开该
命令指定的表;若当前工作区打开的是其他表,
则该命令执行后将在一个新的工作区中打开, 逻
辑删除完成后, 仍保持原当前工作区 。 若指定的
表在非当前工作区中打开, 逻辑删除完成后, 指
定的表仍在原工作区中打开, 且仍保持原当前工
作区 。
Visual FoxPro
59
6.4.3 更新记录
更新记录时对存储在表中的记录进行修改, 命令是
UPDATE,也可以对用 SELECT语句选择出的记录
进行数据更新 。
UPDATE [<数据库名 >!]<表名 >
SET<字段名 1>=<表达式 1>[,<字段名 2>=<表达式 2>… ]
[WHERE<逻辑表达式 >]
该命令用指定的新值更新记录 。
Visual FoxPro
60
例 将, 学生, 表中胡敏杰学生的籍贯改为广东 。
UPDATE 学生 SET 籍贯 =′广东 ′ WHERE 姓名 =′胡
敏杰 ′
例 所有男生的各科成绩加 20
UPDATE 选课 SET 成绩 =成绩 +20
WHERE学号 IN( SELECT 学号 FROM 学生
WHERE 性别 =′男 ′)
以上命令中, 用到了 WHERE条件运算符, IN”
和对用 SELECT语句选择出的记录进行数据更新 。
注意 UPDATE一次只能在单一的表中更新记录 。