第4章 关系数据库标准语言SQL 4.1 SQL语言概述 4.2 SQL数据查询功能 4.3 SQL数据操作功能 4.4 SQL数据定义功能
4.1 概述 SQL是结构化查询语言Structured Query Language的缩写。 4.1 概述 SQL是结构化查询语言Structured Query Language的缩写。 可以说查询是SQL语言的重要组成部分,但不是全部,SQL还包含数据定义、数据操纵和数据控制功能等部分。 SQL已经成为关系数据库的标准数据语言,所以现在所有的关系数据库管理系统都支持SQL.
4.1 概述 SQL语言具有如下主要特点: ①SQL是一种一体化的语言,它包括了数据定义、数据查询、数据操纵和数据控制等方面的功能,它可以完成数据库活动中的全部工作。 ②SQL语言是一种高度非过程化的语言 ③SQL语言非常简洁。虽然SQL语言功能很强,但它只有为数不多的几条命令。 ④SQL语言可在命令窗口或程序中交互使用。
表4.1 SQL命令动词 SQL功能 作用 命令动词 数据查询 查询 SELECT 数据操纵 插入 INSERT 更新 UPDATE 删除 DELETE 数据定义 新建 CREATE DROP 修改 ALTER
4.2 查询功能 回顾: 专门关系运算p13 选择:从关系中找出满足给定条件的元组的操作称为选择。 4.2 查询功能 回顾: 专门关系运算p13 选择:从关系中找出满足给定条件的元组的操作称为选择。 投影:从关系模式中指定若干个属性组成新的关系称为投影。 连接: 将两个表按给定的连接条件,将第一个关系中的所有记录逐个与第二个关系的所有记录按条件进行连接(连接),即选择两个关系在连接属性上满足条件的元组拼接成一个新的关系的运算。 自然联接: 当连接属性具有相同属性名,连接条件取相等条件时,去掉重复属性的等值连接称为自然连接。
SQL的核心是查询。 SQL的查询命令也称作SELECT命令,它的基本形式由SELECT-FROM-WHERE查询块组成,多个查询块可以嵌套执行。 即:select 查询什么 from 从哪来 where 查询条件 VFP的SQL SELECT命令的语法格式如下:(见书p128) Select 字段名1,字段名2, …from 表名 where 条件
GROUP BY短语用于对查询结果进行分组,可以利用它进行分组汇总; HAVING短语必须跟随GROUP BY使用,它用来限定分组必须满足的条件; ORDER BY短语用来对查询的结果进行排序。
4.2.1 简单查询 基于单个表的查询,可以有简单的查询条件。这样的查询由SELECT和FROM短语构成无条件查询,或由SELECT 、 from 、 WHERE短语组成条件查询。 例4.1 从职工表中检索所有工资值。 SELECT 工资 FROM 职工 SELECT 职工号,工资 FROM 职工 从此表名中找 要显示的字段名
例4.2 检索仓库关系中的所有元组。 可以看到在结果中有重复值,如果要去掉重复值只需要指定DISTINCT短语: SELECT DISTINCT 工资 FROM 职工 DISTINCT 短语的作用是去掉查询结果中的重复值。 例4.2 检索仓库关系中的所有元组。 select * from 仓库 * 代表要显示的所有字段
例4.3 检索工资多于1230元的职工号。 例4.4 检索哪些仓库号有工资多于1210元的职工。 例4.3 检索工资多于1230元的职工号。 Select 职工号 from 职工 where 工资>1230 WHERE短语指定了查询条件,查询条件可以是任意复杂的逻辑表达式。 例4.4 检索哪些仓库号有工资多于1210元的职工。 SELECT DISTINCT 仓库号 from 职工 WHERE 工资>1210
例4.5 给出在仓库“WHl”或“WH2”工作,并且工资少于1250元的职工号。 SELECT 职工号 FROM 职工; WHERE 工资<1250 AND (仓库号=“WH1” OR 仓库号=“WH2”) 注意:这里的分号是续行符号,下同。
4.2.2 简单的连接查询 select 职工号,城市 from 职工,仓库; 4.2.2 简单的连接查询 联接是关系的基本操作之一,联接查询是一种基于多个关系的查询。 例4.6找出工资多于1230元的职工号和他们所在的城市。 select 职工号,城市 from 职工,仓库; where (工资>1230) and (职工.仓库号=仓库.仓库号) 表中字段 表名
如果在检索命令的FROM之后有两个关系,那么这两个关系之间肯定有一种联系,否则无法构成检索表达式。从前面的讨论可知,仓库关系和职工关系之间存在着一个一对多的联系。
例4.7 找出工作在面积大于400的仓库的职工号以及这些职工工作所在的城市。 select 职工号,城市 from 职工,仓库; where (面积>400) and (职工.仓库号=仓库.仓库号)
4.2.3 嵌套查询 基于多个关系的查询,这类查询所要求的结果出自一个关系,但相关的条件却涉及多个关系。 4.2.3 嵌套查询 基于多个关系的查询,这类查询所要求的结果出自一个关系,但相关的条件却涉及多个关系。 例4.8 哪些城市至少有一个仓库的职工工资为1250元? 这个例子要求查询仓库表中的城市信息,而查询条件是职工表的工资字段值,为此可以使用如下的嵌套查询: SELECT 城市 FROM 仓库 WHERE 仓库号 in; (SELECT 仓库号 FROM 职工 WHERE 工资=1250) 这里IN相当于集合运算符∈
例4.9 查询所有职工的工资都多于1210元的仓库的信息。 例4.9 查询所有职工的工资都多于1210元的仓库的信息。 这个检索要求也可以描述为:没有一个职工的工资少于或等于1210元的仓库的信息。 这样可以有SQL命令: SELECT * FROM 仓库 WHERE 仓库号 NOT IN; (SELECT 仓库号 FROM 职工 WHERE ; 工资<=1210) 不在以下范围
例4.10 找出和职工E4同样工资的所有职工。 Select 职工号 FROM 职工 WHERE 工资=; (SELECT 工资 FROM 职工 WHERE 职工号="E4")
4.2.4 几个特殊运算符 BETWEEN…AND… (…和…之间) LIKE是字符串匹配运算符 通配符“%”表示0个或多个字符 “_”表示一个字符
例5.12 从供应商表中检索出全部公司的信息,不要工厂或其他供应商的信息。 例4.11检索工资在1220到1240元之间的职工。 Select * from 职工 where 工资 between 1220 and 1240 例5.12 从供应商表中检索出全部公司的信息,不要工厂或其他供应商的信息。 Select * from 供应商 where 供应商名 like "%公司"
Select * from 供应商 where 地址 !="北京" 例4.13 找出不在北京的全部供应商信息。 Select * from 供应商 where 地址 !="北京" 不等于,也可用 not(地址=“北京”)
4.2.5 排序 使用SQL SELECT可以将查询结果排序,排序的短语是ORDER BY,可以按升序(ASC)或降序(DESC)排序,允许按一列或多列排序。 例4.14按职工的工资值升序检索出全部职工信息。 SELECT * FROM 职工 ORDER BY 工资 字段名
例4.15 先按仓库号排序,再按工资排序并输出全部职工信息。 例4.15 先按仓库号排序,再按工资排序并输出全部职工信息。 SELECT * FROM 职工 ORDER BY 仓库号,工资 注意:ORDER BY是对最终的查询结果进行排序,不可以在子查询中使用该短语。
4.2.6 简单的计算查询 SQL不仅具有一般的检索能力,而且还有计算方式的检索。用于计算检索的函数有: ①COUNT—计数 ②SUM—求和 4.2.6 简单的计算查询 SQL不仅具有一般的检索能力,而且还有计算方式的检索。用于计算检索的函数有: ①COUNT—计数 ②SUM—求和 ②AVG—计算平均值 ④MAX—求最大值 ⑤MIN —求最小值 这些函数可以用在SELECT短语中对查询结果进行计算。
注意:除非对关系(表)中的元组(记录)个数进行计数,一般COUNT函数应该使用DISTINCT。 例4.16 找出供应商所在地的数目。 SELECT COUNT(DISTINCT 地址) FROM 供应商 注意:除非对关系(表)中的元组(记录)个数进行计数,一般COUNT函数应该使用DISTINCT。
例4.17 求支付的工资总数。 SELECT SUM(工资) FROM 职工 结果是:6160 这个结果是职工关系中的工资值的总和,它并不管是否有重复值。 若使用命令: SELECT SUM(DISTINCT 工资) FROM 职工 将得出错误的结果4910。
例4.18 求北京和上海的仓库职工的工资总和。 SELE SUM(工资) FROM 职工 WHERE 仓库号 IN; 例4.18 求北京和上海的仓库职工的工资总和。 SELE SUM(工资) FROM 职工 WHERE 仓库号 IN; (SELECT 仓库号 FROM 仓库 WHERE 城市="北京" OR 城市="上海" 例4.19 求所有职工的工资都多于1210元的仓库的平均面积。 SELECT AVG(面积) FROM 仓库 WHERE 仓库号 NOT IN; (SELECT 仓库号 FROM 职工 WHERE 工资<=1210) 例4.20 求在WH2仓库工作的职工的最高工资值。 SELECT MAX(工资) FROM 职工 WHERE 仓库号="WH2"
4.2.7 分组与计算查询 利用GROUP BY子句进行分组计算查询。 GROUP BY短语的格式如下: 4.2.7 分组与计算查询 利用GROUP BY子句进行分组计算查询。 GROUP BY短语的格式如下: Group by 字段名 having 条件 可以按一列或多列分组,还可以用HAVING进一步限定分组的条件。 例4.21 求每个仓库的职工的平均工资。 SELECT 仓库号,AVG(工资) FROM 职工 GROUP BY 仓库号
结果是: WHl l230 WH2 1235 WH3 1230 在这个查询中,首先按仓库号属性进行分组,然后再计算每个仓库的平均工资。
例4.22 求至少有两个职工的每个仓库的平均工资。 例4.22 求至少有两个职工的每个仓库的平均工资。 SELECT 仓库号,COUNT(*),AVG(工资) FROM 职工; GROUP BY 仓库号 HAVING COUNT(*)>=2 结果是: WHl 21230 WH2 21235 HAVING子句总是跟在GROUP BY子句之后,不可以单独使用。
SQL支持空值,当然也可以利用空值进行查询。 4.2.8 利用空值查询 SQL支持空值,当然也可以利用空值进行查询。 假设在订购单关系中,一名职工正在准备订购单,但尚未选定供应商,这样若把信息存入数据库,则供应商号和订购日期两个属性均为空值,在前面给出的订购单记录中有3个这样的记录。
例4.23 找出尚未确定供应商的订购单。 结果是: E6 NUIL OR77 NULI E1 NULL OR80 NUIJL 例4.23 找出尚未确定供应商的订购单。 SELECT * FROM 订购单 WHERE 供应商号 IS NULL 结果是: E6 NUIL OR77 NULI E1 NULL OR80 NUIJL E3 NUIJL OR90 NULL 注意:查询空值时要使用IS NULL,而=NULL是无效的,因为空值不是一个确定的值,所以不能用“=”这样的运算符进行比较。
例4.24 列出已经确定了供应商的订购单信息。 结果是: E3 S7 OR67 2001/06/23 例4.24 列出已经确定了供应商的订购单信息。 SELECT *FROM 订购单 WHERE 供应商号 IS NOT NULL 结果是: E3 S7 OR67 2001/06/23 E1 S4 OR73 2001/07/28 E7 S4 OR76 2001/05/25 E3 S4 OR79 2001/06/13 E3 S3 OR91 2001/07/13
4.2.9 别名与自连接查询 在连接操作中,经常需要使用关系名作前缀,有时这样显得很麻烦。因此,SQL允许在FROM短语中为关系名定义别名, 4.2.9 别名与自连接查询 在连接操作中,经常需要使用关系名作前缀,有时这样显得很麻烦。因此,SQL允许在FROM短语中为关系名定义别名, 格式为: <关系名> <别名>
比如,如下的联接语句是一个基于4个关系的联接查询,其中必须使用关系名作前缀: select 供应商名 from 供应商,订购单,职工,仓库; where 地址="北京" AND 城市="北京" ; and 供应商.供应商号=订购单.供应商号; and 订购单.职工号=职工.职工号; and 职工.仓库号=仓库.仓库号
在上面的查询中,如果使用别名就会简单一些,如下是使用了别名的同样的联接查询语句: select 供应商名 from 供应商 S,订购单 P,职工 E,仓库 W; where 地址="北京" AND 城市="北京" ; and S.供应商号=P.供应商号; and P.职工号=E.职工号; and E.仓库号=W.仓库号
4.2.10 内外层互相关嵌套查询 例4.26 列出每个职工经手的具有最高总金额的订购单信息。 4.2.10 内外层互相关嵌套查询 例4.26 列出每个职工经手的具有最高总金额的订购单信息。 SELECT out.职工号,out.供应商号,out.订购单号,; out.订购日期,out.总金额; FROM 订购单 out WHERE 总金额=; (SELECT MAX(总金额) FROM 订购单 innerl; WHERE out.职工号=innerl.职工号)
在这个查询中,外层查询和内层查询使用同一个关系,给它们分别指定别名out和innerl。 内层查询利用这个职工号值,确定该职工经手的具有最高总金额的订购单的总金额; 随后外层查询再根据out关系的同一元组的总金额值与该总金额值进行比较,如果相等,则该元组被选择。
4.2.11 使用量词和谓词的查询 子查询有关的运算符,它们有以下两种形式: <表达式><比较运算符>[ANY|ALL|SOME](子查询) [NOT] EXISTS(子查询) ANY、ALL和SOME是量词,其中ANY和SOME是同义词. EXISTS是谓词,EXISTS或NOT EXISTS是用来检查在子查询中是否有结果返回,即存在元组或不存在元组。
例4.27 检索那些仓库中还没有职工的仓库的信息。 这里的查询是没有职工或不存在职工,所以可以使用谓词NOT EXISTS: 例4.27 检索那些仓库中还没有职工的仓库的信息。 这里的查询是没有职工或不存在职工,所以可以使用谓词NOT EXISTS: SELECT * FROM 仓库 WHERE NOT EXISTS; (SELECT * FROM 职工 WHERE 仓库号=仓库.仓库号) 以上的查询等价于: SELECT * FROM 仓库 WHERE 仓库号 NOT IN; (SELECT 仓库号 FROM 职工)
例4.28 检索那些仓库中至少已经有一个职工的仓库的信息。 例4.28 检索那些仓库中至少已经有一个职工的仓库的信息。 SELECT* FROM 仓库 WHERE EXISTS; (SELE * FROM 职工 WHER 仓库号=仓库.仓库号) 它等价于: SELECT * FROM 仓库 WHERE 仓库号 IN; (SELECT 仓库号 FROM 职工) 注意:[NOT]EXISTS只是判断子查询中是否有或没有结果返回,它本身并没有任何运算或比较。
例4.29检索有职工的工资大于或等于WH1仓库中任何一名职工工资的仓库号。 这个查询可以使用ANY或SOME量词。 SELECT DISTINCT 仓库号 FROM 职工 WHERE 工资>=ANY; (SELECT 工资 FROM 职工 WHER 仓库号="WH1") 它等价于: SELECT DISTINCT 仓库号 FROM 职工 WHER 工资>=; (SELECT MIN(工资) FROM 职工 WHER 仓库号="WH1")
ANY、ALL谓词与函数及IN谓词的等价转换关系 = <>或!= < <= > >= ANY IN <MAX <=MAX >MIN >=MIN ALL NOT IN <MIN <=MIN >MAX >=MAX
5.2.12 超联接查询 在一般SQL中超联接运算符是“*=”和“=*”。 其中“*=”称为左联接,含义是在结果表中包含第一个表中满足条件的所有记录;如果有在联接条件上匹配的元组,则第二个表返回相应值,否则第二个表返回空值; 而“=*”称为右联接,含义是在结果表中包含第二个表中满足条件的所有记录;如果有在联接条件上匹配的元组,则第一个表返回相应值,否则第一个表返回空值。 注意:VFP不支持超联接运算符“*=”和“=*”
VFP有专门的联接运算语法格式,它支持超联接查询,联接运算有关的语法格式如下: SELECT …… FROM 表名 INNER |LEFT|RIGHT| FULL JOIN 表 ON 联接条件 WHERE …. 其中: INNER JOIN=JOIN,为普通的联接,在VFP称内部联接。 LEFT JOIN为左联接。 RIGHT JOIN为右联接。 FULL JOIN可以称为全联接,即两个表中的记录不管是否满足联接条件将都在目标表或查询结果中出现,不满足联接条件的记录对应部分为NULL。
例4.31:普通联接,即只有满足联接条件的记录才出现在查询结果中。 SELECT 仓库.仓库号,城市,面积,职工号,工资; FROM 仓库 JOIN 职工; ON 仓库.仓库号=职工.仓库号 如下两种命令格式也是等价的: FROM 仓库 INNER Join 职工; 和 FROM 仓库,职工 WHERE 仓库.仓库号=职工.仓库号
例4.32左联接,即除满足连接条件的记录出现在查询结果中外,第一个表中不满足联接条件的记录也出现在查询结果中。 SELECT 仓库.仓库号,城市,面积,职工号,工资; FROM 仓库 LEFT JOIN 职工; ON 仓库.仓库号=职工.仓库号 右联接:除满足连接条件的记录出现在查询结果中外,第二个表中不满足联接条件的记录也出现在查询结果中. 全联接:两个表中不满足联接条件的记录也出现在查询结果中。
注意:VFP的SQL SELECT语句的连接格式只能实现两个表的连接,如果要实现多个表的连接,还需要使用标准格式。 例如下面是一个基于4个关系的连接查询: SELECT 仓库.仓库号,城市,供应商名,地址; FROM 供应商,订购单,职工,仓库; WHERE 供应商.供应商号=订购单.供应商号; AND 订购单.职工号=职工.职工号; AND 职工.仓库号=仓库.仓库号
4.2.13集合的并运算 SQL支持集合的并(UNION)运算,即可以将两个SELECT语句的查询结果通过并运算合并成一个查询结果。 为了进行并运算,要求这样的两个查询结果具有相同的字段个数,并且对应字段的值要出自同一个值域,即具有相同的数据类型和取值范围。
例如,如下语句的结果是城市为北京和上海的仓库信息: SELECT * FROM 仓库 WHERE 城市="北京"; UNION; SELECT * FROM 仓库 WHERE 城市="上海"
4.2.14 VFP中SQL SELECT的几个特殊选项 1.显示部分结果 有时只需要满足条件的前几个记录,这时使用TOP nExpr [PERCENT]短语非常有用. 当不使用PERCENT时, nExpr 是l至32767间的整数,说明显示前几个记录;当使用PERCENT时,nExpr是0.01至99.99间的实数,说明显示结果中前百分之几的记录。 需要注意的是TOP短语要与ORDER BY短语同时使用才有效。
例4.35 显示工资最高的三位职工的信息。 例4.36 显示工资最低的那30%职工的信息。 SELECT * TOP 3 FROM 职工 ORDER BY 工资 DESC 例4.36 显示工资最低的那30%职工的信息。 SELECT *TOP 30 PERCENT FROM 职工 ORDER BY 工资
2.将查询结果存放到数组中 可以使用“INTO ARRAY 数组名”短语将查询结果存放到数组中。 如将查询到的职工信息存放在数组tmp中: SELECT * FROM 职工 INTO ARRAY tmp tmp(1,1)存放的是第一条记录的仓库号字段值, tmp(1,3)存放的是第一条记录的工资字段值等。
3.将查询结果存放在临时文件中 使用短语INTO CURSOR cursorName可以将查询结果存放到临时数据表文件中. 其中cursorName是临时文件名,该短语产生的临时文件是一个只读的dbf文件,当查询结束后该临时文件是当前文件,可以像一般的dbf文件一样使用,但仅是只读。当关闭文件时该文件将自动删除。 如将查询到的职工信息存放在临时dbf文件tmp中:。 SELECT * FROM 职工 INTO CURSOR tmp
4.将查询结果存放到永久表中 使用短语“INTo DBF |TABLE 表名”可以将查询结果存放到永久表中(dbf文件)。 比如将例4.36的查询结果存放在表hh中可以使用如下语句: SELECT * TOP 3 FROM 职工 INTO TABLE hh; ORDER BY 工资 DESC
5.将查询结果存放到文本文件中 6.将查询结果直接输出到打印机 使用短语TO FILE 文件名 [ADDITIVE]可以将查询结果存放到 文本文件中. 如将查询结果以文本的形式存在hnp.txt中: SELECT *TOP 3 FROM 职工 TO FILE hnp ORDER BY; 工资 DESC 如果TO短语和INTO短语同时使用,则To短语将会被忽略。 6.将查询结果直接输出到打印机 使用短语TO PRINTER[PROMPT]可以直接将查询结果输出到打印机.
VFP在支持标准SQL方面还有一些限制和遗憾,例如不支持多层嵌套查询、不支持COMPUTE短语等。
4.3操作功能 SQL的操作功能是指对数据库中数据的操作功能,主要包括数据的插入、更新和删除三个方面的内容。
4.3.1插入数据 VFP支持两种SQL插入命令的格式,第一种格式是标准格式,第二种格式是VFP的特殊格式。 第一种格式: INSERT INTO 表名[(字段1[,字段2…])] VALUES (记录值1,记录值2,…) 例如: insert into 学生 values(911111,"张三",21,"男")
第二种格式: INSERT INTO 表名 FROM ARRAY 数组名 | FROM MEMVAR 其中: FROM MEMVAR说明根据同名的内存变量来插入记录值,如果同名的变量不存在,那么相应的字段为默认值或空。
例如,往订购单关系中插入元组: (”E7”,”S4”,”OR01“,2001/05/25) 可用如下命令: INSERT INTO 订购单; VALUES("E7","S4","OR01",{^2001-05-25},1111) 注意:这里日期型数据的表示方式。 如果供应商号尚未确定,则先只能插入两个属性的值: INSERT INTO 订购单(职工号,订购单号); VALUES("E9","OR01")
注意: 当一个表定义了主索引或候选索引后,由于相应的字段具有关键字的特性,即不能为空,所以只能用此命令插入记录。FoxPro以前的插入命令(INSERT或APPEND)是先插入一条空记录,然后再输入各字段的值,由于关键字字段不允许为空,所以使用以前的方法就不能成功地插入记录。
4.3.2更新 SQL的数据更新命令格式如下: UPDATE 表名 SET 字段1=表达式1,字段2=表达式2,… WHERE 条件 一般使用WHERE子句指定条件,以更新满足条件的一些记录的字段值,并且一次可以更新多个字段;如果不使用WHERE子句,则更新全部记录。
例如,给WH1仓库的职工提高10%的工资的命令: UPDATE 职工 SET 工资=工资*1.10; WHERE 仓库号=”WH1” 又如,给所有学生的年龄增加1岁: UPDATE 学生 SET 年龄=年龄+1
4.3.3删除数据 SQL从表中删除数据的命令格式如下: DELETE FROM 表名 [WHERE 条件] 这里FROM指定从哪个表中删除数据,WHERE指定被删除的记录所满足的条件,如果不使用WHERE子句,则删除该表中的全部记录。
例如,要删除仓库关系中仓库号值是WH2的元组,可用命令: DELETE FROM 仓库 WHERE 仓库号="WH2" 注意: 在VFP中SQL DELETE命令同样是逻辑删除记录,如果要物理删除记录需要继续使用PACK命令。
4.4定义功能 标准SQL的数据定义功能非常广泛,一般包括 数据库的定义 表的定义 视图的定义 存储过程的定义 规则的定义 索引的定义等若干部分。
4.4.1 表的定义 通过SQL的CREATE TABLE命令建立表,相应的命令格式是: CREATE TABLE|DBF 表名…… 4.4.1 表的定义 通过SQL的CREATE TABLE命令建立表,相应的命令格式是: CREATE TABLE|DBF 表名…… 简化形式: CREATE TABLE 表名 (字段名1,类型(长度),字段名2,类型(长度) .... )
例4.37用命令建立“订货管理1”数据库。 CREATE TABLE 仓库1(; 仓库号 C(5) PRIMARY KEY,; CREATE DATABASE 订货管理1 建立仓库1表: CREATE TABLE 仓库1(; 仓库号 C(5) PRIMARY KEY,; 城市 C(10),; 面积 I CHECK(面积>0) ERROR"面积应该大于0!")
例4.38用SQL CREATE命令建立职工l表。 CREATE TABLE 职工1(仓库号 C(5),; 职工号 C(5) PRIMARY KEY,; 工资 I CHECK(工资>=1000 AND 工资<=5000); ERROR "工资值的范围在1000-50001" DEFAULT 1200,; FOREIGN KEY 仓库号 TAG 仓库号 REFERENCES 仓库1)
例4.39用SQLCREATE命令建立供应商1表。 CREATE TABLE 供应商1(; 供应商号 C(5) PRIMARY KEY,供应商名 c(20),地址 c(20)) 用SQI CREATE命令建立订购单1表。 CREATE TABLE 订购单1(; 职工号 C(5),供应商号 C(5),订购单号 C(5) PRIMARY KEY,订购日期 D,; FOREIGN KEY 职工号 TAG 职工号 REFERENCES 职工1,; FOREIGN KEY 供应商号 TAG 供应商号 REFERENCES 供应商1)
4.4.2表的删除 删除表的SQL命令是: DROP TABLE 表名 DROP TABLE直接从磁盘上删除所对应的dbf文件。 如果表是数据库中的表并且相应的数据库是当前数据库,则从数据库中删除了表;否则虽然从磁盘上删除了dbf文件,但是记录在数据库dbc文件中的信息却没有删除,此后会出现错误提示。 所以要删除数据库中的表时,最好应使数据库是当前打开的数据库,在数据库中进行操作。
4.4.3表结构的修改 修改表结构的命令是ALTER TABLE,该命令有三种格式。 格式1:ALTER 表名ADD| ALTER| DROP[COLUMN] 可以添加(ADD)的字段或修改(AITER)已有的字段. 例4.40为订购单1表增加一个货币类型的总金额字段。 ALTER TABLE 订购单1; ADD 总金额 Y CHECK 总金额>0 ERROR "总金额应该大于0!"
例4.41将订购单1表的订购单号字段的宽度由原来的5改为6. ALTER TABLE 订购单1 ALTER 订购单号 C(6) 从命令格式可以看出,该格式可以修改字段的类型、宽度、有效性规则、错误信息、默认值,定义主关键字和联系等;但是不能修改字段名,不能删除字段,也不能删除已经定义的规则等。
格式2: ALTER TABLE 表 ALTER[COLUMN] [NULL|NoT NuLL] [SET DEFAULT 表达式] [SET CHECK 表达式][ERROR 提示信息]] [DROP DEFAULT][DROP CHECK] 从命令格式可以看出,该格式主要用于定义、修改和删除有效性规则和默认值定义。
ALTER 总金额 SET CHECK 总金额>100 ERROR "总金额应该大于100!" 例4.42修改“总金额”字段的有效性规则。 ALTER TABLE 订购单1; ALTER 总金额 SET CHECK 总金额>100 ERROR "总金额应该大于100!" 如下命令删除了“总金额”的有效性规则: ALTER TABLE 订购单1 ALTER 总金额; DROP CHECK
格式3:ALTER TABLE <表名1> [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 <标识名5>]] [DROP FOREIGN KEY TAG <标识名6> [SAVE]] [RENAME COLUMN <字段名2> TO <字段名3>] [NOVALIDATE]
ALTER TABLE 订购单1; RENAME COLUMN 总金额 to 金额 例4.43将“订购单1”表的“总金额”字段名改为“金额”。 ALTER TABLE 订购单1; RENAME COLUMN 总金额 to 金额 如下命令删除“订购单1”表中的“金额”字段: ALTER TABLE 订购单1 DROP COLUMN 金额