SQL完全教程ppt下载
点此下载ppt教程

第13章  关系数据库标准语言SQL
SQL是Structured Query Language的缩写,即结构化查询语言。它是关系数据库的标准语言。查询是SQL语言的重要组成部分,SQL还包含数据定义、数据操作和数据控制功能等内容。SQL已经成为关系数据库的标准数据语言,所以现在所有的关系数据库管理系统都支持SQL。掌握SQL语法可以更加灵活地建立查询和视图。
13.1  SQL简介  
SQL语言来源于20世纪70年代IBM的一个被称为SEQUEL(Structured English Query Language)的研究项目。20世纪80年代,SQL由ANSI进行了标准化,它包括了定义和操作数据的指令。由于它具有功能丰富、使用方式灵活、语言简洁易学等突出特点,在计算机界深受广大用户欢迎,许多数据库生产厂家都相继推出各自支持SQL标准。1998年4月,ISO提出了具有完整性特征的SQL,并将其定为国际标准,推荐它为标准关系数据库语言。1990年,我国也颁布了《信息处理系统数据库语言SQL》,将其定为中国国家标准。
13.1.1  SQL语言的主要特点
(1)一体化语言。SQL提供了一系列完整的数据定义、数据查询、数据操作和数据控制等方面的功能。用SQL可以实现数据库生命周期中的全部活动,包括简单地定义数据库和表的结构,实现表中数据的录入、修改、删除、查询和维护,数据库重构、数据库安全控制等一系列操作要求。
(2)高度非过程化。SQL和其他数据操作语言不同,SQL是一种非过程性语言,它不必一步步地告诉计算机“如何”去做,用户只需说明做什么操作,而不用说明怎样做,不必了解数据存储的格式及SQL命令的内部,就可方便地对关系数据库进行操作。
(3)语言简洁。虽然SQL的功能很强大,但语法却很简单,只有为数不多的几条命令。表13.1给出了分类的命令动词,从该表可知,它的词汇很少。初学者经过短期的学习就可以使用SQL进行数据库的存取等操作,因此,易学易用是它的最大特点。
(4)统一的语法结构对待不同的工作方式。SQL语言可以直接在VFP的命令窗口以人机交互的方式使用,也可嵌入到程序设计中以程序方式使用,比如,SQL语言写在.PRG文件中也能运行。在书写的时候,如果语句太长,可以用“;”号换行。现在很多数据库应用开发工具都将SQL语言直接融入到自身的语言之中,使用起来更方便,VFP就是如此。这些使用方式为用户提供了灵活的选择余地。此外,尽管SQL的使用方式不同,但SQL语言的语法基本是一致的。
13.1.2  SQL语句的执行
SQL语句可以在命令窗口中执行,也可以作为查询或视图(的内容)被使用,还可以在程序文件被执行。
表13.1  SQL命令动词
——————————————————————
    SQL功能        命令动词
——————————————————————
    数据查询        SELECT
    数据定义        CREATE、DROP、ALTER
    数据操作        INSERT、UPDATE、DELETE
    数据控制        GRANT、REVOKE
——————————————————————
13.2  查询功能
数据库中最常见的操作是数据查询,也是SQL的核心。
13.2.1  SQL语法
SQL给出了简单而又丰富的查询语句形式,SQL的查询命令也称作SELECT命令,它的基本形式由SELECT-FROM-WHERE查询块组成,多个查询块可以嵌套执行。
格式:
    SELECT [ALL|DISTINCT][ TOP〈表达式〉 ]
      [ 〈别名〉 ] 〈Select表达式〉 [AS 〈列名〉 ][, [ 〈别名〉 ]
       〈Select表达式〉 [AS 〈列名〉 ]…]
      FORM[ 〈数据库名〉 !] 〈表名〉 [[AS]Local_Alias]
      [[INNER | LEFT [OUTER] | RIGHT [OUTER] | FULL [OUTER]
          JOIN[ 〈数据库名〉 !] 〈表名〉 [[AS]Local_Alias][ON〈联接条件〉 ]]
      [INTO 〈查询结果〉 |TO FILE 〈文件名〉 [ADDITIVE]
          | TO PRINTER [PROMPT] | TO SCREEN]
      [PREFERENCE PreferenceName][NOCONSOLE][PLAIN][NOWAIT]
      [WHERE 〈联接条件1〉 [AND 〈联接条件2〉…][AND | OR 〈筛选条件〉 …
]]
      [GROUP BY 〈组表达式〉 ][, 〈组表达式〉 …]]
      [HAVING ]〈筛选条件〉 ]
      [UNION [ALL] 〈SELECT命令〉 ]
      [ORDER BY 〈关键字表达式〉 [ASC |DESC] [, 〈关键字表达式〉
      [ASC |DESC]…]]
说明:SELECT-SQL命令的格式包括三个基本子句:SELECT子句、FROM子句、WHERE子句,还包括操作子句:ORDER子句、GROUP子句、UNION子句以及其他一些选项。
1.SELECT子句
SELECT子句用来指定查询结果中的数据。其中:
ALL选项:表示选出的记录中包括重复记录,这时缺省值;DISTINCT则表示选出的记录中不包括重复记录。
TOP〈表达式〉选项:表示在符合条件的记录中,选取指定数量或百分比(〈表达式〉)记录。[〈别名〉]〈Select表达式〉[AS〈列名〉]选项中的别名是字段所在的表名;〈Select表达式〉,可以是字段名或字段表达式;〈列名〉用于指定输出时使用的列标题,可以不同于字段名。
〈Select表达式〉用一个*号来表示时,指定所有的字段。
2.FROM子句
用于指定查询的表与联接类型。其中:
JOIN关键字用于联接其左右两个〈表名〉所指定的表。INNER | LEFT[OUTER] | RIGHT[OUTER] | FULL[OUTER]选项,指定两表联接时的联接类型,联接类型有4种,如表13.2所示。其中的OUTER选项,表示外部联接,即允许满足联接条件的记录,又允许不满足联接条件的记录。若省略OUTER选项,效果不变。
表13.2  联接类型
——————————————————————————————————
联接类型                 意义
——————————————————————————————————
Inner Join(内部联接)        只有满足联接条件的记录包含在结果中
Left Outer Join(左联接)     左表某记录与右表所有记录比较字段值,若有满足联接条件的,则产生一个真实记录;若都有满足,则产生一个含.NULL值的记录。直到右表所有记录都比较完
Right Outer Join(右联接)    右表某记录与左表所有记录比较字段值,若有满足联接条件的,则产生一个真实记录;若都不满足,则产生一个含.NULL值的记录。直到右表所有记录都比较完
Full Jion(完全联接)        先按右联接比较字段值,再按左联接比较字段值。不列入重复记录
—————————————————————————————————————
ON选项:用于指定联接条件。
INTO与TO选项:用于指定查询结果的输出去向,默认查询结果显示在浏览窗口中。INTO选项中的 〈查询结果〉 有3种,如表13.3所示。
13.3  查询结果
————————————————————
  目标                输出形式
—————————————————————
  ARRAY〈数组〉       查询结果输出到数组
  CURSOR〈临时表〉    查询结果输出到临时表
  TABLE | DBF〈表名〉    查询结果输出到表
—————————————————————
TO FILE选项:
表示输出到指定的文本文件,并取代原文件内容。
ADDITIVE选项:表示只添加新数据,不清除原文件的内容。
TO PRINTER选项:表示输出到打印机。
PROMPT选项:表示打印前先显示打印确认框。
TO SCREEN选项:表示输出到屏幕。
PLAIN选项:表示输出时省略字段名。
NOWAIT选项:表示显示浏览窗口后程序继续往下执行。
3.WHERE子句
用来指定查询的条件。其中的 〈联接条件〉 指定一个字段,该字段连接FROM子句中的表。
如果查询中包含不止一个表,就应该为第一个表后的每一个表指定连接条件。
4.其他子句和选项
GROUP BY子句:对记录按〈组表达式〉值分组,常用于分组统计。
HAVING子句:当含有GROUP BY子句时,HAVING子句可用作记录查询的限制条件;无GROUP BY 子句时,HAVING子句的作用如同WHERE子句。
UNION子句:可以用UNION子句嵌入另一个SELECT-SQL命令,使这两个命令的查询结果合并输,但输出字段的类型和宽度必须一致。UNION子句默认组合结果中排除重复行,使用ALL,则允许包含重复行。
ORDER BY子句:指定查询结查中记录按〈关键字表达式〉排序,默认升序。选项ASC表示升序,DESE表示降序。
SELECT查询命令的使用非常灵活,用它可以构造各种各样的查询。本章将通过大量的实例来介绍SELECT命令的使用方法。
13.2.2  简单查询
简单查询只含有基本子句,可有简单的查询条件。
【13.1】在zgda表中,检索所有字段。
    SELECT * FROM zgda
13.2.2  简单查询
【13.2】在zggz表中,检索实发工资大于2000元的记录。
    SELECT 编号,姓名,实发工资 FROM zggz WHERE 实发工资>2000
13.2.2  简单查询
【13.3】在zgda表中,检索所有职称名称。
    SELECT DISTINCT 职称 FROM zgda
【13.4】在zgda表中,检索职称是助教的记录。
    SELECT 编号,姓名,职称 FROM zgda WHERE 职称="助教"
13.2.2  简单查询
【13.5】在zggz表中,检索实发工资小于1000大于1800元的记录。命令执行结果如图13.5所示。
    SELECT 编号,姓名,实发工资 FROM zggz WHERE 实发工资>1000 AND 实发工资<1800
13.2.3  几个特殊运算符
在SQL语句中,WHERE子句后面的联接条件,除了可以使用VFP语言中的关系表达式以及逻辑表达外,还可以使用几个特殊运算符:
(1)[NOT]IN:表示[不]在…之中。
(2)[NOT]BETWEEN…AND…:表示[不]在…之间。
(3)[NOT]LIKE:表示[不]与…匹配。
13.2.3  几个特殊运算符
下面以实例来说明此用法。
说明:
(1)NOT运算符来设计否定条件。
(2)LIKE运算符提供两种字符串匹配方式,一种是使用下划线符号“_”,匹配一个和任意字符,另一种是使用百分号“%”,匹配0个或多个任意字符。
(3)IN运算符,格式为IN(常量1,常量2,…)。含义为查找和常量相等的值。
13.2.3  几个特殊运算符
【13.6】在zgda表中,检索性别是男的记录。
    SELECT DISTINCT 编号,姓名,性别 FROM zgda WHERE 性别 LIKE "男"
可以使用NOT运算符来设计否定条件,检索性别不是男的记录。
    SELECT DISTINCT 编号,姓名,性别 FROM zgda WHERE NOT(性别 LIKE "男")
13.2.3  几个特殊运算符
【13.7】在zgda表中,检索所有姓刘的记录。
    SELECT 编号,姓名 FROM zgda WHERE 姓名 LIKE "刘%"
13.2.3  几个特殊运算符
【13.8】在zgda表中,检索所有姓陈和姜的记录。
    SELECT 编号,姓名 FROM zgda WHERE 姓名 IN("陈","姜")
上式可以改为VFP条件,执行结果是一样的。
    SELECT 编号,姓名 FROM zgda WHERE 姓名="陈" OR 姓名="姜"
图13.8
13.2.4  简单的联接查询
联接是关系的基本操作之一,联接查询是一种基于多个关系的查询。
【13.9】在zgda表和zggz表中,检索实发工资大于2000元的记录。
3.9所示。
    SELECT zgda.编号,zgda.姓名,zggz.实发工资 FROM zgda,zggz;
        WHERE (实发工资>2000) AND (zgda.编号=zggz.编号)
        zgda.编号=zggz.编号            &&编号是联接的条件
13.2.4  简单的联接查询
【13.10】在zgda表和zggz表中,检索职称是讲师, 并且实发工资大于1900元的记录
    SELECT zgda.编号,zgda.姓名,zgda.职称,zggz.实发工资 FROM zgda,zggz;
        WHERE (职称="讲师") AND (实发工资>1900) AND (zgda.编号=zggz.编号)
13.2.5  嵌套查询
嵌套查询是基于多个关系的查询,这类查询所要求的结果出自一个关系,但相关条件却涉及多个关系。这时就需要使用SQL的嵌套查询功能。
格式: 〈表达式〉〈比较运算符〉[ANY|ALL|SOME](〈子查询〉)
            [NOT]EXISTS (〈子查询〉)
说明:
(1)其中的〈比较运算符〉除了在第6章介绍的关系运算符之外,还有前面提到的特殊运算符。
(2)ANY、ALL、SOME是量词,其中ANY和SOME是同义词,在进行比较运算时只要子查询中有一条记录为真,则结果为真;而ALL则要求子查询中的所有记录都为真,结果才为真。
(3)EXISTS是谓词,用来检查子查询中是否有结果返回(是否为空)。NOT EXISTS表示是空的结果集。
13.2.5  嵌套查询
为了讨论嵌套查询,在此引入一个订货管理数据库,此数据库涉及4个表(4 个关系),即仓库表、职工表、订购单表、供应商表,4个表的内容分别如图13.11、13.12、13.13、13.14所示。
13.2.5  嵌套查询
【13.11】在仓库表和职工表中,检索哪些城市至少有一个仓库的职工工资为1250元
SELECT 城市 FROM 仓库 WHERE 仓库号 IN;
        (SELECT 仓库号 FROM 职工 WHERE 工资=1250)
在这个命令中含有两个SELECT-FROM-WHERE查询块,即内层查询块和外层查询块,内层查询块
检索到的仓库号值是WH1和WH2, 这里IN相当于集合运算符∈。这样就可写出等价的命令:
    SELECT 城市 FROM 仓库 WHERE 仓库号 IN("WH1", "WH2")
13.2.5  嵌套查询
【13.12】在仓库表和职工表中,检索所有职工的工资都多于为1210元的仓库信息。
    SELECT * FROM 仓库 WHERE 仓库号 NOT IN;
    (SELECT 仓库号FROM职工 WHERE工资<=1210)
13.2.5  嵌套查询
内层SELECT-FROM-WHERE查询块指出所有职工的工资少于或等于1210元的仓库的仓库号值的集合,在这里该集合只有一个值“WH1”;然后从仓库关系中检索元组的仓库号属性值不在该集合中的每个元组。有的读者也许已经注意到刚才的检索出现了错误,尽管在“武汉”的“WH4”仓库还没有职工,但该仓库的信息也被检索出来了。所以必须认真分析检索要求,写出正确的SQL命令。如果要求排除那些还没有职工的仓库,检索要求可以叙述为:检索所有职工的工资都多于1210元的仓库的信息,并且该仓库至少要有一名职工。这样描述就很清楚了,因为我们对没有职工的仓库不感兴趣。这样,写出的SQL命令也就复杂一些了:
    SELECT * FROM 仓库 WHERE 仓库号 NOT IN;
        (SELECT 仓库号 FROM 职工 WHERE 工资<=1210);
        AND 仓库号 IN(SELECT 仓库号 FROM 职工)
这样内层是两个并列的查询,在结果中将不包含没有职工的仓库信息。
13.2.5  嵌套查询
【13.13】检索出和职工E4挣同样工资的所有职工。
    SELECT 职工号 FROM 职工 WHERE 工资=;
        (SELECT 工资 FROM 职工 WHERE 职工号="E4")
13.2.5  嵌套查询
【13.14】检索出工资在1220元到1240元范围内的职工信息。这个查询的条件值是在什么范围之内,显然可以用BETWEEN…AND…,为此有如下查询语句:
    SELECT * FROM 职工WHERE工资 BETWEEN 1220 AND 1240这里BETWEEN…AND…意思是在“…和…之间”,这个查询的条件等价于:
    (工资>=1220) AND (工资<=1240)
显然使用BETWEEN…AND…表达条件更清晰、更简洁。假如找出工资不在1220元和1240元之间的全部职工信息,可以用命令:
    SELECT * FROM 职工 WHERE工资 NOT BETWEEN 1220 AND 1240命令执行结果如图13.20所示。
13.2.5  嵌套查询
【13.15】在供应商表中,检索出全部公司的信息,不要工厂或其他供应商的信息。这是一个字符串匹配的查询,显然应该使用LIKE运算符:
    SELECT * FROM 供应商 WHERE 供应商名 LIKE "%公司"
这里的LIKE是字符串匹配运算符,通配符“%”表示0个或多个字符,另外还有一个通配符“-”表示一个字符。
13.2.5  嵌套查询
【13.16】在供应商表中,找出不在北京的全部供应商的信息。
    SELECT * FROM 供应商 WHERE 地址!="北京"
在SQL中,“不等于”用“!=”表示。另外还可以用否定运算符NOT写出等价命令:
    SELECT * FROM 供应商 WHERE NOT(地址="北京")
NOT的应用范围很广,比如,可以有NOT IN(例13.12)、NOT BETWEEN等。
13.2.6  排序
SQL中排序操作使用ORDER BY子句。
格式:ORDER BY 〈关键字表达式1〉 [ASC | DESC][, 〈关键字表达式2〉 [ASC | DESC]…]
说明:ASC为升序(默认为升序),DESC为降序。允许按一列或多列排序。
13.2.6  排序
【13.17】在职工表中,按职工的工资值升序检索出全部职工的信息。
SELECT * FROM 职工 ORDER BY 工资
这里ORDER BY是排序子句,如果需要将结果按降序排列,只要加上DESC。
SELECT * FROM 职工 ORDER BY 工资 DESC
13.2.6  排序
【13.18】在职工表中,先按仓库号排序,再按工资排序,并输出全部职工信息。
SELECT * FROM 职工 ORDER BY 仓库号,工资
这里一个按多列排序的例子。
说明:ORDER BY是对最终的查询结果进行排序,不可以在子查询中使用该短语。
13.2.7  简单的计算查询
SQL语言是完备的,也就是说,只要数据是按关系方式存入数据库的,就能构造合适的SQL命令把它检索出来。事实上,SQL不仅具有一般的检索能力,而且还有计算方式的检索,比如检索职工的平均工资、检索某个仓库中职工的最高工资值等。用于计算检索的函数有:
(1)COUNT—计数
(2)SUM—求和
(3)AVG—计算平均值
(4)MAX—求最大值
(5)MIN—求最小值
这些函数可以用在SELECT短语中对查询结果进行计算。
13.2.7  简单的计算查询
【13.19】在供应商表中,找出供应商所在地的数目。
    SELECT COUNT (DISTINCT 地址) FROM 供应商
参见前面给出的供应商的记录值,其中共有5个地址:北京、西安、郑州、上海和深圳。所以结果为5。
说明,除非对关系中的元组个数进行计数,一般应用COUNT函数应该使用DISTINCT。例如:
    SELECT COUNT(*) FROM 供应商
将给出供应商关系中的记录数是6个。
13.2.7  简单的计算查询
【13.20】在职工表中,求支付的工资总数。
    SELECT SUM(工资) FROM 职工
结果是:6160。这个结果是职工关系中的工资值的总和,它并不管是否有重复值。这时若使用命令:
    SELECT SUM(DISTINCT工资) FROM 职工
将得出错误的结果4910。原因是DISTINCT命令去掉重复值1250。
13.2.7  简单的计算查询
【13.21】在职工表和仓库表中,求北京和上海的仓库职工的工资总和。
SELECT SUM(工资) FROM 职工WHERE仓库号IN;
(SELECT 仓库号 FROM 仓库 WHERE 城市="北京" OR 城市="上海")
13.2.7  简单的计算查询
13.22  在仓库表和职工表中,求所有职工的工资都多于1210元的仓库的平均面积。
    SELECT AVG(面积) FROM 仓库 WHERE 仓库号 NOT IN;
        (SELECT 仓库号 FROM 职工 WHERE 工资<=1210)
结果是:366.67
这里要注意,以上结果的运算包含了尚没有职工的WH4仓库。如果要排除没有职工的仓库,以上语句应该改为:
    SELECT AVG(面积) FROM 仓库 WHERE 仓库号 NOT IN;
        (SELECT 仓库号 FROM 职工 WHERE 工资<=1210);
          AND仓库号 IN (SELECT仓库号 FROM 职工)
13.2.7  简单的计算查询
【13.23】在职工表中,求在WH2仓库工作的职工的最高工资值。
    SELECT MAX(工资) FROM 职工 WHERE 仓库号="WH2"
结果是:1250
与MAX函数相对应的是MIN函数(求最小值)。比如,求最低工资值可以有如下命令:
    SELECT MIN(工资) FROM 职工 WHERE仓库号="WH2"
13.2.8  分组与计算查询
上面几个例子是对整个关系的计算查询,而利用GROUP BY子句可以进行分组计算查询,使用得更加广泛。格式:GROUP BY 〈分组字段名〉[〈分组字段名〉…][HAVING〈过滤条件〉]可以按一列或多列分组,还可以用HAVING进一步限定分组的条件。下面是几个分组计算查询的例子。
13.2.8  分组与计算查询
【13.24】在职工表中,求每个仓库的职工的平均工资。
    SELECT 仓库号,AVG(工资) FROM 职工 GROUP BY 仓库号
在这个查询中,首先按仓库号属性进行分组,然后再计算每个仓库的平均工资。GROUP BY子句一般跟在WHERE子句之后,没有WHERE子句时,跟在FROM子句之后。另外,还可以根据多个属性进行分组。在分组查询时,有时要求分组满足某个条件时才检索,这时可以用HAVING子句来限定分组。
13.2.8  分组与计算查询
【13.25】在职工表中,求至少有两个职工的每个仓库的平均工资。
    SELECT 仓库号,COUNT(*),AVG(工资) FROM职工;
        GROUP BY 仓库号 HAVING COUNT(*)>=2
HAVING子句总是跟在GROUP BY 子句之后,不可以单独使用。HAVING子句和WHERE 子句不矛盾,在查询中是先用WHERE子句限定元组,然后再进行分组,最后再用HAVING子句限定分组。
说明:HAVING子句和WHERE子句的区别:WHERE子句是用来指定表中各行所应满足的条件,而
HAVING子句是用来指定每一分组所满足的条件,只有满足HAVING条件的那些组才能在结果中被显示。
13.2.9  别名的使用
在联接操作中,经常需要使用关系名作前缀,有时这样显得很麻烦。因此,SQL允许在FROM短语中为关系名定义别名。
格式:〈关系名〉〈别名〉
例如:如下的联接语句是一个基于4个关系的联接查询,其中必须使用关系名作前缀:
    SELECT 供应商名 FROM 供应商,订购单,职工,仓库;
        WHERE 地址="北京" AND 城市="北京";
        AND 供应商.供应商号=订购单.供应商号;
        AND 订购单.职工=职工.职工号;
        AND 职工.仓库号=仓库.仓库号
13.2.9  别名的使用
在上面的查询中,如果使用别名就会简单一些,如下是使用了别名的同样的联接查询语句:
    SELECT 供应商名 FROM 供应商 S,订购单 P,职工 E,仓库 W;
        WHERE 地址="北京"AND 城市="北京";
        AND S.供应商号=P.供应商号;
        AND P.职工号=E.职工号;
        AND E.仓库号=W.仓库号
FROM 供应商 S,订购单 P,职工 E,仓库 W,用S、P、E和W分别代表供应商表、订购单表
、职工表和仓库表。
说明:在嵌套的SQL子句中不能使用外层定义的别名。
13.2.10  内外层互相关嵌套查询
嵌套查询都是外层查询依赖于内层查询的结果,而内层查询与外层查询无关。事实上,有时也需要内、外层互相关的查询,这时内层查询的条件需要外层查询提供值,而外层查询的条件需要内层查询的结果。
13.2.10  内外层互相关嵌套查询
【13.26】在订购单表中,列出每个职工经手的具有最高总金额的订购单信息。这里先给出相应的查询语句,然后再作必要的解释。
    SELECT out.职工号,out.供应商号,out.订购单号,out.订购日期,out.总金额;
        FROM 订购单 out WHERE 总金额=(SELECT MAX(总金额) FROM 订购单 inner1;
        WHERE out.职工号=inner1.职工号)
13.2.10  内外层互相关嵌套查询
在这个查询中,外层查询和内层查询使用同一个关系:订购单表,给他们分别指定别名out和inner1。外层查询提供out关系中每个元组的职工号值给内层查询使用;内层查询利用这个职工号值,确定该职工经手的具有最高总金额的订购单和总金额;随后外层查询再根据out关系的同一元组的总金额与该总金额值进行比较,如果相等,则该元组被选择。
13.2.11  使用量词和谓词的查询
前面已经使用过和嵌套查询或子查询有关的IN和NOT IN运算符,除此之外还有两类和子查询有关的运算符。
格式:〈表达式〉〈比较运算符〉[ANY|ALL|SOME](子查询)
        [NOT]EXISTS(子查询)
ANY、ALL和SOME是量词,其中ANY和SOME是同义词,在进行比较运算时只要子查询中有一行能使结果为真,则结果就为真。ALL则要求子查询中的所有行都使结果为真时,结果才为真。
EXISTS是谓词,EXISTS或NOT EXISTS是用来检查在子查询中是否有结果返回,即存在元组或不存在元组。
13.2.11  使用量词和谓词的查询
下面通过几个例子来理解这些量词和谓词在查询中的用法和用途。
【13.27】在仓库表和职工表中,检索哪些仓库中还没有职工的仓库的信息。
13.2.11  使用量词和谓词的查询
这里的查询是没有职工或不存在职工,所以可以使用谓词NOT EXISTS。
    SELECT * FROM 仓库 WHERE NOT EXISTS;
        (SELECT * FROM 职工 WHERE 仓库号=仓库.仓库号)
说明:这里的内层查询引用了外层查询的表,只有这样使用谓词EXISTS或NOT EXISTS 才有意义。所以这类查询也都是内、外层互相关嵌套查询。
以上的查询命令等价于如下查询命令:
    SELECT * FROM 仓库 WHERE 仓库号 NOT IN (SELECT 仓库号 FROM 职工)
13.2.11  使用量词和谓词的查询
【13.28】在仓库表和职工中,检索哪些仓库中至少已经有一个职工的仓库的信息。
    SELECT * FROM 仓库 WHERE EXISTS;
   (SELECT * FROM 职工 WHERE 仓库号=仓库.仓库号)
说明:[NOT]EXISTS只是判断子查询中是否有或没有结果返回,它本身并没有任何运算或比较。
13.2.11  使用量词和谓词的查询
【13.29】在职工表中, 检索有职工的工资大于或等于WH1仓库中任何一名职工工资的仓库号。
这个查询可以使用ANY或SOME量词。
    SELECT DISTINCT 仓库号 FROM 职工 WHERE 工资>=ANY;
        (SELECT 工资 FROM 职工 WHERE 仓库号="WH1")
它等价于:
    SELECT DISTINCT 仓库号 FROM 职工 WHERE 工资>=;
        (SELECT MIN(工资) FROM 职工 WHERE 仓库号="WH1")
13.2.11  使用量词和谓词的查询
【13.30】在职工表中, 检索有职工的工资大于或等于WH1仓库中所有职工工资的仓库号。这个查询使用ALL量词。
    SELECT DISTINCT 仓库号 FROM 职工 WHERE 工资>=ALL;
        (SELECT 工资 FROM 职工 WHERE 仓库号="WH1")
它等价于:
    SELECT DISTINCT 仓库号 FROM 职工 WHERE 工资>=;
        (SELECT MAX(工资) FROM 职工 WHERE 仓库号="WH1")
13.2.12  超联接查询
SQL中FROM子句后的联接称为超联接,超联接有四种形式。
格式:FROM 〈表名〉 [[INNER | LEFT [OUTER] | RIGHT [OUTER] | FULL [OUTER]
      JOIN [ 〈数据库名〉 !] 〈表名〉 [[AS] Local_Alias][ON 〈联接条件〉]]
说明:OUTER关键字可被省略,包含OUTER强调这是一个外连接(outer join)。
13.2.12  超联接查询
下面我们分别以几个实例来说明这四种超联接的含义及区别。
1.内部联接
使用INNER JOIN形式的联接称为内部联接,INNER JOIN等价于JOIN。INNER JOIN与普通联接相同:只有满足条件的记录才出现在查询结果中。
内部联接是满足联接条件的记录才出现在查询结果中。
13.2.12  超联接查询
【13.31】将仓库表和职工表的职工号字段联接在一起。
    SELECT 仓库.仓库号,城市,面积,职工号,工资;
    FROM 仓库 JOIN职工ON 仓库.仓库号=职工.仓库号
如下两种命令格式也是等价的:
    SELECT 仓库.仓库号,城市,面积,职工号,工资;
        FROM 仓库 INNER JOIN 职工ON 仓库.仓库号=职工.仓库号和
    SELECT 仓库.仓库号,城市,面积,职工号,工资;
        FROM 仓库,职工WHERE仓库.仓库号=职工.仓库号
13.2.12  超联接查询
2.左联接
使用LEFT[OUTER ] JOIN称为左联接,在查询结果中包含JOIN左侧表中的所有记录,以及JOIN右侧表中匹配的记录。
左联接,即除满足联接条件的记录出现在查询结果中外,第一个表中不满足联接条件的记录
也出现在查询结果中。
13.2.12  超联接查询
【13.32】将仓库表和职工表的职工号和工资字段联接在一起。
    SELECT 仓库.仓库号,城市,面积,职工号,工资;
        FROM 仓库 LEFT JOIN 职工;
        ON 仓库.仓库号=职工.仓库号
从以上查询结果中可以看到,首先以左边表即A表中的第一条记录为准,在B表中查询,找到了,则显示,找不到相应的字段以NULL显示,本例中有相应的值。以下记录也是按照这种方法进行查询的。
13.2.12  超联接查询
3.右联接
使用RIGHT [OUTER ] JOIN称为右联接,在查询结果中包含JOIN右侧表中的所有记录,以及JOIN左侧表中匹配的记录。
为了看到右联接和全联接的效果,假设在职工表中插入了如下一条记录:
    "WH8","E8",1200
右联接,即除满足联接条件的记录出现在查询结果中外,第二个表中不满足联接条件的记录也出现在查询结果中。
13.2.12  超联接查询
【13.33】将仓库表和职工表的职工号和工资字段联接在一起。
  SELECT 仓库.仓库号,城市,面积,职工号,工资;
        FROM 仓库 RIGHT JOIN 职工 ON 仓库.仓库号=职工.仓库号
实际上职工“E8”所在的仓库并不存在,这在实际应用中是不允许的。
13.2.12  超联接查询
4.完全联接
FULL [OUTER] JOIN称为完全联接,在查询结果中包含JOIN两侧所有的匹配记录和不匹配
的记录。
完全联接,即除满足联接条件的记录出现在查询结果中外,两个表中不满足联接条件的记录也出现在查询结果中。
13.2.12  超联接查询
【13.34】将仓库表和职工表的职工号和工资字段联接在一起。
    SELECT 仓库.仓库号,城市,面积,职工号,工资;
        FROM 仓库 FULL JOIN职工 ON 仓库.仓库号=职工.仓库号
说明:Visual FoxPro的SQL SELECT语句的联接格式只能实现两个表的联接,如果要实现多个表的联接,还需要使用标准格式。
13.2.12  超联接查询
例如下面是一个基于4个关系的联接查询。
SELECT 仓库.仓库号,城市,供应商名,地址;
        FROM 供应商,订购单,职工,仓库;
        WHERE 供应商.供应商号=订购单.供应商号;
        AND 订购单.职工号=职工.职工号;
        AND 职工.仓库号=仓库.仓库号
这样的查询用Visual FoxPro的专门格式就写不出来了。
13.2.13  集合的并运算
使用UNION子句可以进行集合的并运算,即可以将两个SELECT语句的查询结果合并成一个查询结果。当然,要求进行并运算的两个查询结果具有相同的字段个数,并且对应字段的值要具有相同的数据类型和取值范围。格式:〈Selcct命令1〉UNION [ALL]〈Selcct命令2〉
说明:
(1)可以使用多个UNION子句,ALL选项防止删除合并结果中重复的行(记录)。
(2)不能使用UNION来组合子查询。
(3)只有最后的〈Selcct命令〉中可以包含ORDER BY子句,而且必须按编号指出排序的列(它
将影响整个结果)。
13.2.13  集合的并运算
【13.35】在仓库表中,显示城市为北京和上海的仓库信息。
    SELECT * FROM 仓库 WHERE 城市="北京";
        UNION;
        SELECT * FROM 仓库 WHERE 城市="上海"
13.2.14  查询输出去向
1.显示部分结果
格式: TOP 〈表达式〉[PERCENT]
功能:显示需要满足条件的前几个记录。
说明:
(1)〈表达式〉是数字表达式,当不使用PERCENT时,〈表达式〉是1至32 767间的整数,说明显示前几个记录。
(2)当使用PERCENT时,〈表达式〉是0.01至99.99间的实数,说明显示结果中前百分之几的记录。需要注意的是TOP短语要与ORDERBY短语同时使用才有效。
13.2.14  查询输出去向
【13.36】在职工表中, 显示工资最高的三位职工的信息。
SELECT * TOP 3 FROM 职工 ORDER BY 工资 DESC
【13.37】在职工表中, 显示工资最低的那30%职工的信息。命令执行结果如图13.47所示。
    SELECT * TOP 30 PERCENT FROM 职工 ORDER BY 工资
13.2.14  查询输出去向
2.将查询结果存放到数组中
格式: INTO ARRAY 〈数组名〉
功能: 将查询结果存放到数组中。
说明: 〈数组名〉可以是任意的数组变量名。一般将存放查询结果的数组作为二维数组来使用,每行一条记录,每列对应于查询结果一列。查询结果存放在数组中,可以非常方便地在程序中使用。
13.2.14  查询输出去向
【13.38】将查询到的职工信息存放在数组T1中。
    SELECT * FROM 职工 INTO ARRAY T1
T1(1,1)存放的是第一条记录的仓库号字段值,T1(1,3)存放的是第一条记录的工资字段值等。
13.2.14  查询输出去向
3.将查询结果存放在临时文件中
格式: INTO CURSOR〈临时表〉
功能:将查询结果存放到临时数据库文件中。
说明: 〈临时表〉是 临时文件名,该短语产生的临时文件是一个只读dbf文件,当查询结束后该临时文件是当前文件,可能像一般的dbf文件一样使用,但仅是只读。当关闭文件时该文件将自动删除。
13.2.14  查询输出去向
【13.39】将查询到的职工表信息存放在临时dbf文件T2中。
    SELECT * FROM 职工 INTO CURSOR T2
一般利用INTO CURSOR短语存放一些临时结果,比如一些复杂的汇总可能需要分阶段完成,需要根据几个中间结果再汇总等,这时利用该短语存放中间结果就非常合适,当使用完后临时文件会自动删除。
13.2.14  查询输出去向
4.将查询结果存放到永久表中
格式: INTO DBF|TABLE 〈表名〉
功能: 可以将查询结果存放到永久表中(dbf文件)。
13.2.14  查询输出去向
【13.40】在职工表中, 显示工资最高的三位职工的信息,查询结果存放在表Al中。
    SELECT * TOP 3 FROM 职工 INTO TABLE A1 ORDER BY 工资 DESC
13.2.14  查询输出去向
5.将查询结果存放到文本文件中
格式:TO FILE 〈文本文件名〉 [ADDITIVE]
功能:可以将查询结果存放到文本文件中。
说明:文本文件名(默认扩展名是txt),如果使用ADDITIVE选项,结果将追加在原文件的尾部,否则将覆盖原有文件。
13.2.14  查询输出去向
【13.41】将查询结果以文本的形式存储在文本文件A2.txt中。
    SELECT * TOP 3 FROM 职工 TO FILF A2 ORDER BY 工资 DESC
如果TO短语和INTO短语同时使用,则TO短语将会被忽略。
13.2.14  查询输出去向
6.将查询结果直接输出到屏幕
格式:TO SCREEN
功能:将查询结果输出到屏幕。
13.2.14  查询输出去向
7.将查询结果直接输出到打印机
格式:TO PRINTER [PROMPT]
功能:将查询结果输出到打印机,如果使用了PROMPT选项,在开始打印之前会打开打印机设置对话框。FROM 子句中INTO 与TO选项,用于指定查询结果的输出去向,默认查询结果显示在浏览窗口中。INTO选项中的〈查询结果〉有3种:ARRAY〈数组〉、CURSOR〈临时表〉、TABLE | DBF〈表名〉。TO选项也有3种:文本文件、屏幕、打印机。
13.2.14  查询输出去向
本节用大量实例介绍了SQL SELECT语句的使用方法,这些实例都可以在Visual FoxPro下执行。掌握SQL SELECT不仅对学好、用好Visual FoxPro至关重要,也是以后使用其他数据库或开发数据库应用程序的基础。
13.3  操作功能
SQL语言的操作功能包括对表中数据的增加、删除和更新操作。
13.3.1  插入
在一个表的尾部追加数据时,要用到插入功能,SQL的插入命令包括以下3种格式:
格式:
INSERT INTO 〈表名〉 [(〈字段名1〉 [,〈字段名2〉,…])]
         VALUES(〈表达式1〉)[, 〈表达式2〉,…])

          INSERT INTO 〈表名〉 FROM ARRAY  〈数组名〉
          INSERT INTO 〈表名〉 FROM MEMVAR
功能:3种格式都是在指定的表的表尾添加一条新记录。
13.3.1  插入
说明:
(1)第1种格式其值为VALUES后面的表达式的值。当需要插入表中所有字段的数据时,表名后面的字段名可以缺省,但插入数据的格式必须与表的结构完成吻合;若只需要插入表中某些字段的数据,就需要列出插入数据的字段,当然相应表达式的数据位置会与之对应。
(2)第2种格式新记录的值是指定的数组中各元素的数据。数组中各元素与表中各字段顺序对应。如果数组中元素的数据类型与其对应的字段类型不一致,则新记录对应的字段为空值;如果表中字段个数大于数组元素的个数,则多的字段为空值。
(3)第3种格式新记录的值是指定的内存变量的值。添加的新记录的值是与指定表各字段名同名的内存变量的值,如果同名的内存变量不存在,则相应的字段为空。
Visual FoxPro支持两种SQL插入命令的格式,第一种格式是标准格式,第二种格式是Visual FoxPro的特殊格式。
13.3.1  插入
【13.42】在订购单表中,插入元组("E7","S4","OR01",09/25/03)。
    INSERT INTO 订购单(职工号,供应商号,订购单号,订购日期,总金额)
        VALUES("E7","S4","OR01",{^2003-09-25},1200)
其中“{^2003-09-25}”是日期型字段订购日期的值。
图13.48
13.3.1  插入
假设供应商尚未确定,那么只能先插入职工号和订购单号两个属性的值,这时可用如下命令:
    INSERT INTO 订购单(职工号,订购单号) VALUES("E7","OR01")
这时另外三个属性的值为空。
13.3.1  插入
下面用一组命令来说明INSERT INTO…FROM ARRAY 的使用方式:
    USE订购单                         &&打开订购单
    SCATTER to A1                      &&将当前记录读到数组A1
    COPY STRUCTURE TO A2               &&拷贝订购单表的结构到A2
    INSERT INTO A2 FROM ARRAY A1       &&从数组A1插入一条记录到A2
    SELECT A2                          &&切换到A2的工作区
    BROWSE                             &&用BROWSE命令验证插入的结果
    USE                                &&关闭A2.dbf文件
    DELETE FILE A2.dbf                 &&删除A2.dbf文件
13.3.1  插入
在一个表的尾部追加数据时,要用到插入功能,SQL的插入命令包括以下3种格式:
格式:
INSERT INTO 〈表名〉 [(〈字段名1〉 [,〈字段名2〉,…])]
          VALUES(〈表达式1〉)[, 〈表达式2〉,…])

          INSERT INTO 〈表名〉 FROM ARRAY  〈数组名〉
          INSERT INTO 〈表名〉 FROM MEMVAR
功能:3种格式都是在指定的表的表尾添加一条新记录。
13.3.1  插入
说明:
(1)第1种格式其值为VALUES后面的表达式的值。当需要插入表中所有字段的数据时,表名后面的字段名可以缺省,但插入数据的格式必须与表的结构完成吻合;若只需要插入表中某些字段的数据,就需要列出插入数据的字段,当然相应表达式的数据位置会与之对应。
(2)第2种格式新记录的值是指定的数组中各元素的数据。数组中各元素与表中各字段顺序对应。如果数组中元素的数据类型与其对应的字段类型不一致,则新记录对应的字段为空值;如果表中字段个数大于数组元素的个数,则多的字段为空值。
(3)第3种格式新记录的值是指定的内存变量的值。添加的新记录的值是与指定表各字段名同名的内存变量的值,如果同名的内存变量不存在,则相应的字段为空。
Visual FoxPro支持两种SQL插入命令的格式,第一种格式是标准格式,第二种格式是Visual FoxPro的特殊格式。
13.3.1  插入
【13.42】在订购单表中,插入元组("E7","S4","OR01",09/25/03)。命令执行结果如图13.48所示。
    INSERT INTO 订购单(职工号,供应商号,订购单号,订购日期,总金额)
        VALUES("E7","S4","OR01",{^2003-09-25},1200)
其中“{^2003-09-25}”是日期型字段订购日期的值。
图13.48
13.3.1  插入
假设供应商尚未确定,那么只能先插入职工号和订购单号两个属性的值,这时可用如下命令:
    INSERT INTO 订购单(职工号,订购单号) VALUES("E7","OR01")
这时另外三个属性的值为空。
13.3.1  插入
下面用一组命令来说明INSERT INTO…FROM ARRAY 的使用方式:
    USE订购单                         &&打开订购单
    SCATTER to A1                      &&将当前记录读到数组A1
    COPY STRUCTURE TO A2               &&拷贝订购单表的结构到A2
    INSERT INTO A2 FROM ARRAY A1       &&从数组A1插入一条记录到A2
    SELECT A2                          &&切换到A2的工作区
    BROWSE                             &&用BROWSE命令验证插入的结果
    USE                                &&关闭A2.dbf文件
    DELETE FILE A2.dbf                 &&删除A2.dbf文件
13.3.1  插入
用下面一组命令来说明INSERT INTO…FROM MEMVAR的使用方式:
    USE订购单                         &&打开订购单
    SCATTER M1                         &&将当前记录读到内存变量M1中
    COPY STRUCTURE TO A2               &&拷贝订购单表的结构到A2
    INSETR INTO A2 FROM M1             &&从内存变量插入一条记录到A2
    SELECT A2                          &&切换到A2的工作区
    BROWSE                             &&用BROWSE命令验证插入的结果
    USE                                &&关闭A2.dbf文件
    DELETE FILE A2.dbf                 &&删除A2.dbf文件
13.3.1  插入
说明:当一个表定义了主索引或候选索引后,由于相应的字段具有关键字的特性,即不能为空,所以只能用此命令插入记录。FoxPro以前的插入命令(INSERT或APPEND)是先插入一条空记录,然后再输入各字段的值,由于关键字字段不允许为空,所以使用以前的方法就不能成功地插入记录。
13.3.2  更新
更新是指对存储在表中的记录进行修改。
格式:
UPDATE [ 〈数据库〉! ] 〈表名〉
          SET 〈列名1〉=〈表达式1〉 [, 〈列名2〉=〈表达式2〉 …]
          [WHERE 〈条件表达式1〉 [AND | OR 〈条件表达式2〉 …]]
13.3.2  更新
说明:
(1)[〈数据库〉! ] 〈表名〉:指定要更新数据的记录所在的表名及该表所在的数据库名。
(2)SET 〈列名〉=〈表达式〉:指定被更新的字段及该字段的新值。如果省略WHERE子句,则该字段每一条都用同样的值更新。
(3)WHERE 〈条件表达式〉:指明将要更新数据的记录。即更新表中符合条件表达式的记录,并且一次可以更新多个字段;如果不使用WHERE子句,则更新全部记录。
13.3.2  更新
【13.43】在职工表中,给WH1仓库的职工提高10%的工资。命令执行结果如图13.49所示。
    UPDATE 职工 SET 工资=工资*1.10 WHERE 仓库号="WH1"
例如: 将所有学生的年龄增加1岁:
         UPDATE 学生 SET 年龄=年龄+1
图13.49
13.3.3  删除
用SQL语言可以删除数据表中的记录。
格式:
DELETE FROM  [〈数据库!〉 ] 〈表名〉
        [WHERE 〈条件表达式1〉 [AND | OR 〈条件表达式2〉 …]]
说明:
(1)[〈数据库!〉 ] 〈表名〉:指定加删除标记的表名及该表所在的数据库名,用“!”分割表名和数据库名,数据库名为可选项。
(2)WHERE选项:指明只对满足条件的记录加删除标记。如果不使用WHERE子句,则删除该表中的全部记录。
(3)上述删除只是加删除标记,并没有从物理上删除,只有执行了PACK命令,有删除标记的记录才能真正从表中删除。删除标记可以用REACLL命令取消。
13.3.3  删除
【13.44】删除仓库表中仓库号值是WH2的记录。
    DELETE FROM 仓库 WHERE仓库号="WH2"
说明:SQL DELETE命令同样是逻辑删除记录,如果要物理删除记录需要继续使用PACK命令。
13.4  定义功能
标准SQL的数据定义功能非常广泛,一般包括数据库的定义、表的定义、视图的定义、存储过程的定义、规则的定义和索引的定义等若干部分。在本节将主要介绍Visual FoxPro支持的表定义功能和视图定义功能。
13.4.1  表结构的定义
在第3章中已介绍了通过表设计器建立表的方法,在Visual FoxPro中也可以通过SQL的CREATE TABLE命令建立表。
现在介绍怎样利用SQL命令来建立相同的数据库,然后可以利用数据库设计器和表设计器来检验用SQL建立的数据库,读者可以从中作一些对比。表结构的定义是指创建一个含有指定字段的表。
13.4.1  表结构的定义
格式:
    CREATE TABLE |DBF  〈表名1〉 [NAME  〈长表名〉  ][FREE]
        (〈字段名1〉 〈类型〉 [ (〈字段宽度〉  [, 〈小数位数〉  ]) ]
        [NULL | NOT NULL]
        [CHECK 〈逻辑表达式1〉  [ERROR 〈字符型文本信息1〉 ]]
        [DEFAULT 〈表达式1〉 ]
        [PRIMARY KEY | UNIQUE]
        [REFERENCES 〈表名2〉 [TAG  〈标识名1〉 ]]
        [NOCPTRANS][,〈字段名2〉 …]
        [,PRIMARY KEY  〈表达式2〉  TAG  〈标识名2〉
        |,UNIQUE  〈表达式3〉  TAG  〈标识3〉]
        [,FOREIGN KEY  〈表达式4〉  TAG  〈标识名4〉  [NODUP]
            REFERENCES  〈表名3〉  [TAG  〈标识名5〉 ]]
        [,CHECK 〈逻辑表达式2〉  [ERROR 〈字符型文本信息2〉] ])
        |FROM ARRAY 〈数组名〉
13.4.1  表结构的定义
说明:用CREATE TABLE命令可以完成第3章中介绍的“表设计器”具有的所有操作。
(1)TABLE和DBF选项等价,都是建立表文件。
(2)〈表名〉:为新建表指定表名。
(3) NAME〈长表名〉:为新建表指定一个长表名。只有打开数据库,在数据库中创建表时,才能指定一个长表名。长表名最多可以包含128个字符。
(4)FREE:建立的表是自由表,不加入到打开的数据库中。当没有打开数据库时,建立的表都是自由表。
(5) 〈字段名1〉〈类型〉[ (〈字段宽度〉[,〈小数位数〉] ) ]:指定字段名、字段类型、字段宽度及小数位数。字段类型可以用一个字符表示。
(6)NULL:允许该字段值为空;NOT NULL:该字段值不能为空。缺省值为NOT NULL。
(7)CHECK〈逻辑表达式1〉:指定该字段的合法值及该字段值的约束条件。
(8)ERROR〈字符型文本信息1〉:指定在浏览或编辑窗口中该字段输入的值不符合CHECK子句的合法值时,VFP显示的错误信息。
(9)DEFAULT〈表达式〉:为该字段指定一个缺省值,表达式的数据类型与该字段的数据类型要一致。即每添加一条记录时,该字段自动取该缺省值。
(10)PRIMARY KEY:为该字段创建一个主索引,索引标识名与字段名相同。主索引字段值必须惟一。UNIQUE:为该字段创建一个候选索引,索引标识名与字段名相同。
(11)REFERENCES 〈表名〉  [TAG  〈标识名〉 ]:指定建立持久关系的父表,同时以该字段为索引关键字建立外索引,用该字段名作为索引标识名。表名为父表表名,标识名为父表中的索引标识名。如果省略索引标识名,则用父表的主索引关键字建立关系,否则不能省略。如果指定了索引标识名,则在父表中存在索引标识字段上建立关系。父表不能是自由表。
(12)CHECK 〈逻辑表达式2〉[ERROR 〈字符型文本信息2〉 ]:由逻辑表达式指定表的合法值。不合法时,显示由字符型文本信息指定的错误信息。该信息只有在浏览或编辑窗口中修改数据时显示。
(13)FROM ARRAY 〈数组名〉:由数组创建表结构。数组名指定的数组包含表的每一个字段的字段名、字段类型、字段宽度及小数位数。
用SQL命令来建立的数据表,可以与用“表设计器”建立的表作对比。
13.4.1  表结构的定义
【13.45】用命令建立订货管理1数据库。
    CREATE DATABASE D:\VFP1\订货管理1   &&建立订货管理1数据库
用SQL CREATE命令建立仓库1表。
    OPEN DATABASE 订货管理1              &&打开订货管理1数据库
        CREATE TABLE D:\VFP1\仓库1 (仓库号 C (5) PRIMARY KEY,;
        城市 C (10),面积 I CHECK (面积>0) ERROR "面积应该大于0!")&&建立仓库表1
13.4.1  表结构的定义
说明:
(1)PRIMARY KEY说明仓库号是主索引。
(2)CHECK为面积字段值说明了有效性规则(面积>0) 。
执行完如上命令后在项目管理器中立刻可以看到仓库1表。命令执行结果如图13.50所示。
图13.50
13.4.1  表结构的定义
【13.46】用SQL CREATE 命令建立订购单1表。
    CREATE TABLE D:\VFP1\订购单1(职工号 C (5),供应商号 C (5),;
        订购单号 C (5) PRIMARY KEY, 订购日期 D)
以上所有建立表的命令执行完后可以在数据库设计器中看到如图13.51所示的界面,从中可以看到通过SQL CREATE命令不仅可以建立表,同时还建立起了表之间的联系。然后可以用第4章介绍的方法来编辑参照完整性,进一步完善数据库的设计。
13.4.1  表结构的定义
说明:
(1)用SQL CREATE命令新建的表自动在最低可用工作区打开,并可以通过别名引用,新表的打开方式为独占方式,忽略SET EXCLUSIVE的当前设置。
(2)如果建立自由表(当前没有打开的数据库或使用了FREE),则很多选项在命令中不能使用,如NAME、CHECK、DEFAULT、FOREIGN KEY、PRIMARY KEY和REFERENCES等。
13.4.2  表的删除
随着数据库应用的变化,往往有些表连同它的数据不再需要了,这时可以删除这些表,以节省存储空间。
格式:DROP TABLE 〈表名〉
说明:DROP TABLE直接从磁盘上删除表名所对应的DBF文件。如果表名是数据库中的表,并且相应的数据库是当前数据库,则从数据库中删除表;否则虽然从磁盘上删除了DBF文件,但是记录在数据库DBC文件中的信息却没有删除,此后会出现错误提示。所以要删除数据库中的表时,最好应使数据库是当前打开的数据库,在数据库中进行操作。
13.4.3  表结构的修改
用户使用数据时,随着应用要求的改变,往往需要对原来的表格结构进行修改,修改表结构的SQL命令是ALTER TABLE,该命令格式有三种。
13.4.3  表结构的修改
1.第1种格式
第1种格式的ALTER TABLE命令可以为指定的表添加字段或修改已有的字段。
格式:
    ALTER TABLE 〈表名1〉 ADD | ALTER [COLUMN]
      〈字段名1〉〈字段类型〉[(〈长度〉[,〈小数位数〉])][NULL | NOT NULL]
      [CHECK〈逻辑表达式1〉[ERROR〈字符型文本信息〉]][DEFAULT〈表达式1〉]
      [PRIMARY KEY | UNIQUE][REFERENCES 〈表名2〉 [TAG 〈标识名1〉 ]]
      [NOCPTRANS]
13.4.3  表结构的修改
说明:
(1)〈表名1〉:指明被修改表的表名。
(2)ADD [COLUMN]:该子句指出新增加列的字段名及他们的数据类型等信息。在ADD子句中使用CHECK、PRIMARY KEY、UNIQUE任选项时,需要删除所有数据,否则违反有效性规则,命令不被执行。
(3)ALTER [COLUMN]:该子句指出要修改列的字段名以及他们的数据类型等信息。在ALTER子句中使用CHECK任选项时,需要被修改字段的已有数据满足CHECK规则;使用PRIMARY KEY、UNIQUE任选项时,需要被修改字段的已有数据满足惟一性,不能有重复值。
13.4.3  表结构的修改
【13.47】为订购单1表增加一个整型类型的数量字段。
    ALTER TABLE 订购单1;
        ADD 数量 I CHECK 数量>0 ERROR "数量应该大于0!"
13.4.3  表结构的修改
【13.48】将购单1表的订购单号字段的宽度由原来的5改为6。
    ALTER TABLE 订购单1 ALTER 订购单号 C(6)
从命令格式可以看出,该格式可以修改字段的类型、宽度、有效性规则、错误信息、默认值,定义主关键字和联系等;但是不能修改字段名,不能删除字段,也不能删除已经定义的规则等。
13.4.3  表结构的修改
2.第2种格式
第2种格式的ALTER TABLE命令,主要用于修改指定表中指定字段的DEFAULT和CHECK约束规则,不影响原有表的数据。
格式:
    ALTER TABLE〈表名〉ALTER [COLUMN]〈字段名〉[NULL | NOT NULL]
        [SET DEFAULT 〈表达式〉]
        [SET CHECK 〈逻辑表达式〉[ERROR 〈字符型文本信息〉 ]]
        [DROP DEFAULT] [DROP CHECK]
13.4.3  表结构的修改
说明:
(1)〈表名〉:指明被修改表的表名。
(2)ALTER [COLUMN] 〈字段名〉:指出要修改列的字段名。
(3)NULL | NOT NULL:指定字段可以为空或不能为空。
(4)SET DEFAULT 〈表达式〉:重新设置字段的缺省值。
(5)SET CHECK 〈逻辑表达式〉 [ERROR 〈字符型文本信息〉 ]:重新设置该字段的合法值,要求该字段的原有数据满足合法值。
(6)DROP DEFAULT:删除缺省值。
(7)DROP CHECK:删除该字段的合法限定。
13.4.3  表结构的修改
【13.49】修改或定义数量字段的有效性规则。
    ALTER TABLE 订购单1;
        ALTER 数量 SET CHECK 数量>0 ERROR "数量应该大于0"
13.4.3  表结构的修改
【13.50】删除数量字段的有效性规则。
    ALTER TABLE 订购单1 ALTER 数量 DROP CHECK
以上两种格式都不能删除字段,也不能更改字段名。第3格式正是在这些方面对前两种格式的补充。
13.4.3  表结构的修改
3.第3种格式
第3种格式的ALTER TABLE命令,可以删除指定表中的指定字段、修改字段名、修改指定表完整性规则,包括添加或删除主索引、外索引、候选索引及表的合法值限定。
格式:
    ALTER TABLE 〈表名〉 [DROP [COLUMN] 〈字段名1〉 ]
      [SET CHECK 〈逻辑表达式1〉[ERROR〈字符型文本信息〉]]
      [DROP CHECK]
      [ADD PRIMARY KEY〈表达式1〉TAG〈标识名1〉[FOR〈逻辑表达式2〉 ]]
      [DROP PRIMARY KEY]
      [ADD UNIQUE 〈表达式2〉 [TAG 〈标识名2〉[FOR〈逻辑表达式3〉 ]]]
      [DROP UNIQUE TAG〈标识名3〉]
      [ADD FOREIGN KEY [〈表达式3〉][TAG〈标识名4〉][FOR〈逻辑表达式4〉]
          REFERENCES 表名2 [TAG〈标识名4〉 ]]
      [DROP FOREIGN KEY TAG〈标识名5〉 [SAVE]]
      [RENAME COLUMN〈字段名2〉TO〈字段名3〉 ]
      [NOVALIDATE]
13.4.3  表结构的修改
说明:
(1)DROP[COLUMN] 〈字段名〉:从指定表中删除指定的字段。
(2)SET CHECK 〈逻辑表达式〉 [ERROR〈字符型文本信息〉]:为该表指定合法值及错误提示信息。DROP CHECK:删除该表的合法值限定。
(3)ADD PRIMARY KEY 〈表达式〉 TAG 〈标识名〉:为该表建立主索引,一个表只能有一个主索引。DROP PRIMARY KEY:删除该表的主索引。
(4)ADD UNIQUE 〈表达式〉 [TAG 〈标识名〉 ]:为该表建立候选索引,一个表可以有多个候选索引。DROP UIQUE TAG〈标识名〉:删除该表的候选索引。
(5)ADD FOREIGN KEY:为该表建立外(非主)索引,与指定的父表建立关系,一个表可以有多个外索引。
(6)DROP FOREIGN KEY TAG〈标识名〉:删除外索引,取消与父表的关系,SAVE子句将保存该索引。
(7)RENAME COLUMN 〈字段名2〉TO〈字段名3〉:修改字段名,字段名2指定要修改的字段名,字段名3指定新的字段名。
(8)NOVALIDATE:修改表结构时,允许违反该表的数据完整性规则,默认值为禁止违反数据完整性规则。
注意:修改自由表时,不能使用DEFAULT,FOREIGN KEY,PRIMARY KEY,REFERENCES或SET子句。
13.4.3  表结构的修改
【13.51】将订购单1表的总金额字段名改为金额。
    ALTER TABLE 订购单1 RENAME COLUMN 总金额 TO 金额
13.4.3  表结构的修改
【13.52】删除订购单1表中的金额字段。
    ALTER TABLE 订购单1 DROP COLUMN 金额
13.4.3  表结构的修改
【13.53】将订购单1表的职工号和供应商号定义为候选索引(候选关键字),索引名是e1。
    ALTER TABLE 订购单1 ADD UNIQUE 职工号+供应商号 TAG e1
13.4.3  表结构的修改
【13.54】删除订购单1表中的候选索引e1。
    ALTER TABLE 订购单1 DROP UNIQUE TAG e1
13.4.4  视图的定义
在Visual FoxPro中视图是一个定制的虚拟表,可以是本地的、远程的或带参数的。视图可引用一个或多个表,或者引用其他视图。视图是可更新的,它可引用远程表。
在关系数据库中,视图也称作窗口,即视图是操作表的窗口,可以把它看作是从表中派生出
来的虚表。它依赖于表,但不独立存在。
在第5章中已经介绍了如何使用“视图设计器”来创建视图,本节介绍如何利用SQL语言
13.4.4  视图的定义
建立视图。视图是根据对表的查询定义的。
格式:CREATE [SQL] VIEW〈视图名〉[(〈字段名1〉[, 〈字段名2〉]… )]AS〈查询语句〉
说明:
(1)〈查询语句〉:可以是任意的SELECT查询语句,它说明并限制了视图中的数据。如果没有为视图指定字段名,视图中的字段名将与〈查询语句〉中指定的字段名相同。
(2)视图必须建立在数据库中。
1.从单个表派生出的视图
13.4.4  视图的定义
【13.55】在职工表中定义视图。
       CREATE VIEW W1 AS;
        SELECT 职工号,仓库号 FROM 职工
                                          
13.4.4  视图的定义
其中W1是视图的名称。视图一经定义,就可以和基本表一样进行各种查询,也可以进行一些修改操作。对于最终用户来说,有时并不需要知道操作的是基本表还是视图。为了查询职工号和仓库号信息,可以有命令:
    SELECT * FROM  W1
或  SELECT 职工号,仓库号 FROM W1
或  SELECT 职工号,仓库号 FROM 职工
13.4.4  视图的定义
3个命令效果相同。
上面是限定列构成的视图,下面再限定行定义一个视图。
13.4.4  视图的定义
【13.56】在职工表中,查询北京仓库的信息,定义如下视图。
       CREATE VIEW W2 AS;
        SELECT * FROM 仓库 WHERE 城市="北京"
这里W2中只有北京仓库的信息。
13.4.4  视图的定义
2.从多个表派生出的视图
从上面的例子可以看出,视图一方面可以限定对数据的访问,另一方面又可以简化对数据的访问。
13.4.4  视图的定义
【13.57】在订购单表中,列出每个职工经手的具有最高总金额的订购单信息, 定义视图。
        CREATE VIEW W3 AS;
        SELECT out.职工号,out.供应商号,out.订购单号,out.订购日期,out.总金额;
        FROM 订购单 out WHERE 总金额=;
        (SELECT MAX(总金额)FROM 订购单 inner1;
        WHERE out.职工号=inner1.职工号)
这时候再提出同样的查询要求,就只需要输入以下命令即可:
    SELECT * FROM W3
13.4.4  视图的定义
【13.58】定义视图向用户提供职工号、职工的工资和职工工作所在城市的信息。
       CREATE VIEW W4 AS;
        SELECT 职工号,工资,城市 FROM 职工,仓库;
        WHERE 职工.仓库号=仓库.仓库号
结果对用户就好像有一个包含字段职工号、工资和城市的表。
13.4.4  视图的定义
3.视图中的虚字段
用一个查询来建立一个视图的SELECT子句可以包含算术表达式或函数,这些表达式或函数与视图的其也字段一样对待,由于他们是计算得来的,并不存储在表内,所以称为虚字段。
13.4.4  视图的定义
【13.59】定义一个视图,它包含职工号、月工资和年工资3个字段。
    CREATE VIEW W5 AS;
        SELECT 职工号,工资 AS 月工资,工资*12 AS 年工资 FROM 职工
这里的SELECT短语中利用AS重新定义视图的字段名。由于其中一字段是计算得来的,所以必须给出字段名。这里年工资是虚字段,它是由职工表的工资字段乘以12得到的;而月工资就是职工表中的工资字段,由此可见,在视图中还可以重新命名字段名。
13.4.4  视图的定义
4.视图的删除
由于视图是从表中派生出来的,所以不存在修改结构的问题,但是可以删除视图。
格式:DROP VIEW〈视图名〉
说明:上述命令与VFP中删除视图的命令DELETE VIEW 〈视图名〉等价。
13.4.4  视图的定义
【13.60】删除视图 W4。
    DROP VIEW W4
13.4.4  视图的定义
5.关于视图的说明
在Visual FoxPro中视图是可更新的,但是这种更新是否反映在基本表中则取决于视图更新属性的设置。在Visual FoxPro中视图有它特殊的概念和用途,在关系数据库中,视图始终不真正含有数据,它总是原来表的一个窗口。所以,虽然视图可以像表一样进行各种查询,但是插入、更新和删除操作在视图上却有一定的限制。在一般情况下,当一个视图是由单个表导出时可以进行插入和更新操作,但不能进行删除操作;当视图是从多个表导出时,插入、更新和删除操作都不允许进行。这种限制是很必要的,它可以避免一些潜在问题的发生。
weiking   2006-05-13 23:48:18 评论:4   阅读:4127   引用:0
???????????????????????? ????? @2008-09-26 11:02:12  ?????????
???????????????????????? ??????????
???????????????????????? ??????????????????????????????????????????????????????????? ???С??????????????????????????????????г??ж??а??′?????????????????У?????????????????????????????????????????????????????????????????????????У????????????????????????????????????????j??????????????????????д?????????????????κη??á? ??????? ?????????????????? ??????????????? j??绰??13428760857 j????????
@2008-07-07 21:57:20  游客
   谢谢了,好东西!!
@2007-01-05 21:57:21  游客
怎样才能够下载,谢谢!!!
下载不了 @2007-01-05 21:56:38  游客
ppt 为什么下不了?

发表评论>>

署名发表(评论可管理,不必输入下面的姓名)

姓名:

主题:

内容: 最少15个,最长1000个字符

验证码: (如不清楚,请刷新)

用,就用的漂亮点。文章嘛,借花献佛喽。