- 844.00 KB
- 2022-08-23 发布
- 1、本文档由用户上传,淘文库整理发布,可阅读全部内容。
- 2、本文档内容版权归属内容提供方,所产生的收益全部归内容提供方所有。如果您对本文有版权争议,请立即联系网站客服。
- 3、本文档由用户上传,本站不保证质量和数量令人满意,可能有诸多瑕疵,付费之前,请仔细阅读内容确认后进行付费下载。
- 网站客服QQ:403074932
第六章关系数据库标准语言SQL本章要点:SQL的基本概念SQL的数据查询功能:简单查询、嵌套查询、联接查询、分组和计算查询、集合的并运算SQL的数据操作功能:删除(DELETE-SQL)、插入(INSERT-SQL)、更新(UPDATE-SQL)SQL的数据定义功能:表的定义、表的删除、表结构的修改、视图的定义1\nSQL是结构化查询语言StructuredQueryLanguage的缩写。查询是SQL语言的重要组成部分,但不是全部,SQL还包含数据定义、数据操纵和数据控制功能等部分。现在所有的关系数据库管理系统都支持SQL。FoxPro从2.5ForDOS版就开始支持SQL,现在的VF当然在这方面更加完善。2\n表5.1SQL命令动词SQL功能命令动词数据查询SELECT数据定义CREATE、DROP、ALTER数据操纵INSERT、UPDATE、DELETE数据控制GRANT、REVOKE3\nSQL语言具有如下主要特点:SQL是一种一体化的语言,它包括了数据定义、数据查询、数据操纵和数据控制等方面的功能,它可以完成数据库活动中的全部工作。SQL语言是一种高度非过程化的语言,它没有必要一步步地告诉计算机“如何”去做,而只需要描述清楚用户要“做什么”,SQL语言就可以将要求交给系统,自动完成全部工作。SQL语言非常简洁。SQL语言可以直接以命令方式交互使用,也可以嵌入到程序设计语言中以程序方式使用。VF是将SQL语言直接融入到自身的语言之中,使用起来更方便。4\n查询功能:SELECT[ALL|DISTINCT][<别名>.]<选项>[,[<别名>.]<选项>……]FROM<表名>[<别名>][,<表名>[<别名>]……][WHERE<条件表达式>][AND<条件表达式>……][GROUPBY<分组选项>[,<分组选项>……]][HAVING<组条件表达式>][ORDERBY<排序选项>[ASC|DESC][,<排序选>[ASC|DESC]……]]5\n命令中各参数的含义如下:SELECT是该命令的主要关键字。ALL|DISTINCT表示ALL和DISTINCT任选其一,ALL表示所有的记录,DISTINCT表示去掉重复记录。FROM说明要查询的数据来自哪个或哪些表,可以对单个表或多个表进行查询;WHERE说明查询条件,即选择元组的条件;6\nGROUPBY短语用于对查询结果进行分组,可以利用它进行分组汇总;HAVING短语必须跟随GROUPBY使用,它用来限定分组必须满足的条件;ORDERBY短语用来对查询的结果进行排序7\n简单查询例1、从职工关系中检索所有工资值。SELECT工资FROM职工可以看到在结果中有重复值,若要去掉重复值只需要指定DISTINCT短语。SELECTDISTINCT工资FROM职工8\n2、查询仓库关系中的所有元组。SELECT*FROM仓库9\n3、查询工资多于1230元的职工号。SELECT职工号FROM职工WHERE工资>123010\n4、查询哪些仓库有工资多于1210元的职工。SELECTDISTINCT仓库号FROM职工表WHERE工资>121011\n5、查询在仓库“wh1”或“wh2”工作,并且工资少于1250元的职工号。SELECT职工号FROM职工表;&&(续行符)WHERE工资<1250AND(仓库号=”wh1”OR仓库号=”wh2”)12\n简单的联接查询例:1、查询工资多于1230元的职工号和他们所在的城市。SELECT职工号,城市FROM职工,仓库;WHERE(工资>1230)AND(职工.仓库号=仓库.仓库号注:由表可知,仓库和职工之间存在着一个一对多的联系。当FROM之后的多个关系中含有相同的属性名时,这时必须用关系前缀直接指明属性所属的关系,如职工.仓库号,“.”前关系名,后是属性名13\n2、找出工作在面积大于400的仓库的职工号以及这些职工工作所在的城市。SELECT职工号,城市FROM仓库,职工表;WHERE(面积>400)AND(职工表.仓库号=仓库.仓库号)14\n嵌套查询SELECT嵌套查询是一种子查询,子查询的特征是能够将一个查询的结果作为另一个查询的一部分,子查询是对查询结果的查询。在SQL中,有些查询不用子查询无法表达。子查询要加括号,并且与SELECT语句的形式类似,也有FROM子句,以及可选择的WHERE、GROUPBY和HAVING子句等。子查询中的子句与SELECT语句中的子句格式相同,用于子查询时,它们执行正常的功能,但是子查询和SELECT语句还是有如下区别:15\n(1)子查询通常必须生成单字段数据作为其查询结果,即必须是一个确定的项。若为一个集合,则需要使用谓词演算查询。(2)ORDERBY子句不能用于子查询,子查询结果只是被主查询内部使用,对用户是不可见的,所以对它们的任何排序都是没有意义的。16\n例1、哪些城市至少有一个仓库的职工工资为1250元?SELECT城市FROM仓库WHERE仓库号IN;(SELECT仓库号FROM职工WHERE工资=1250)17\n2.查询所有职工的工资都多于1210元的仓库的信息。此查询也可描述为:没有一个职工的工资少于或等于1210元的仓库的信息。SELECT*FROM仓库WHERE仓库号NOTIN;(SELECT仓库号FROM职工表WHERE工资<=1210)18\n注:尽管在“武汉“的”wh4”仓库还没有职工,但该仓库的信息也被检索出来了,所以必须认真分析检索要求,写出正确的SQL命令。如果要求排除那些还没有职工的仓库,检索要求可以叙述为:检索所有职工的工资都多于1210元的仓库的信息,并且该仓库至少要有一名职工。SELECT*FROM仓库WHERE仓库号NOTIN;(SELECT仓库号FROM职工表WHERE工资<=1210);AND仓库号IN(SELECT仓库号FROM职工表)19\n3、找出和职工E4挣同样工资的所有职工。SELECT职工号FROM职工表WHERE工资=;(SELECT工资FROM职工表WHERE职工号=”e4”)20\n几个特殊运算符BETWEEN…AND…:指定查询的条件是在什么范围内(数值)LIKE(%|_):指定查询与通配符相匹配的字符。21\n例1、查询出工资在1220元到1240元范围内的职工信息。SELECT*FROM职工表WHERE工资BETWEEN1220AND1240(工资>=1220AND工资<=1240)22\n2、从供应商关系中检索出全部公司的信息,不要工厂或其他供应商的信息。这是一个字符串匹配的查询,显然应该使用LIKE运算符。SELECT*FROM供应商WHERE供应商名LIKE“%公司”23\n3、找出不在北京的全部供应商信息。SELECT*FROM供应商WHERE地址!=“北京”SELECT*FROM供应商WHERENOT(地址=“北京”)NOT的应用范围很广,比如,可以有NOTIN、NOTBETWEEN等。若提出和例1相反的请求,找出工资不在1220元和1240元之间的全部职工信息,可以用命令:SELECT*FROM职工表WHERE工资NOTBETWEEN1220AND124024\n排 序使用SQL-SELECT可以将查询结果排序,排的短语是ORDERBY,具体格式如下:ORDERBY字段1[ASC|DESC][,字段2][ASC|DESC…]由以上格式可看出,可以按升序(ASC)或降序(DESC)排序,允许按一列或多列排序。25\n1、按职工的工资值升序检索出全部职工信息。SELECT*FROM职工表ORDERBY工资26\n2、先按仓库号排序,再按工资排序并输出全部职工信息。SELECT*FROM职工表ORDERBY仓库号,工资注:ORDERBY是对最终的查询结果进行排序,不可以在子查询中使用该短语。27\n简单的计算查询SQL命令不仅具有一般的检索能力,而且还有计算方式的检索,比如检索职工的平均工资、检索某个仓库中职工的最高工资值等。用于计算检索的函数有:(1)COUNT-计数(2)SUM-求和(3)AVG-计算平均值(4)MAX-求最大值(5)MIN-求最小值这些函数可以用在SELECT短语中对查询结果进行计算。28\n1、找出供应商所在地的数目。SELECTCOUNT(DISTINCT地址)FROM供应商注:除非对关系中的元组个数进行计数,一般COUNT函数应该使用DISTINCT。如:SELECTCOUNT(*)FROM供应商将给出供应商关系中的记录数。29\n2、求支付的工资总数。SELECTSUM(工资)FROM职工这个结果是职工关系中的工资值的总和,它并不管是否有重复值。这时若使用命令:SELECTSUM(DISTINCT工资)FROM职工3、求北京和上海的仓库职工的工资总和。SELECTSUM(工资)FROM职工表WHERE仓库号IN;(SELECT仓库号FROM仓库WHERE城市=”北京”OR城市=”上海”)4、求所有职工的工资都多于1210元的仓库的平均面积。SELECTAVG(面积)FROM职工表WHERE仓库号NOTIN;(SELECT仓库号FROM职工表WHERE工资<=1210)30\n注:以上结果的运算包含了没有职工的wh4仓库。若要排除没有职工的仓库,就改为:SELECTAVG(工资)FROM职工表WHERE仓库号NOTIN;(SELECT仓库号FROM职工表WHERE工资<=1210);AND仓库号IN(SELECT仓库号FROM职工表)31\n5、求在wh2仓库工作的职工的最高工资值。SELECTMAX(工资)FROM职工表WHERE仓库号=”wh2”与MAX函数相对应的是MIN函数(求最小值)。若求最低工资值可以有如下命令:SELECTMIN(工资)FROM职工表WHERE=”wh2”32\n分组与计算查询利用GROUPBY子句进行分组计算查询,格式如下:GROUPBY字段1[,字段2][HAVING条件]可以按一列或多列分组,还可以用HAVING进一步限定分组的条件。33\n1、求每个仓库职工的平均工资SELECT仓库号,AVG(工资)FROM职工表;GROUPBY仓库号在这个查询中,首先按仓库号属性进行分组,然后再计算每个仓库的平均工资。GROUPBY子句一般跟在WHERE子句之后,没有WHERE子句时,跟在FROM子句之后。另外,还可以根据多个属性进行分组。在分组查询时,有时要求分组满足某个条件时才检索,这时可以用HAVING子句来限定分组。34\n2、求至少有两个职工的每个仓库的平均工资。SELECT仓库号,COUNT(*),AVG(工资)FROM职工表;GROUPBY仓库号HAVINGCOUNT(*)>=2注:HAVING子句总是跟在GROUPBY子句之后,不可以单独使用。HAVING子句和WHER子句不矛盾,在查询中是先用WHERE子句限定元组,然后进行分组,最后再用HAVING子句限定分组。35\n利用空值查询在第四章介绍过空值的概念,SQL支持空值,当然也可以利用空值进行查询。ISNULL|ISNOTNULL假设在订购单关系中,一名职工正在准备订购单,但尚未选定供应商,这样若把信息存入数据库,则供应商号和订购日期两个属性均为空值。36\n1、找出尚未确定供应商的订购单。SELECT*FROM订购单WHERE供应商号ISNULL注:查询空值是要使用ISNULL,而=NULL是无效的,因为空值不是一个确定的值,所以不能用”=”运算符进行比较。37\n2、列出已经确定了供应商的订购单信息。SELECT*FROM订购单WHERE供应商号ISNOTNULL38\n别名与自联接查询在联接操作中,经常需要使用关系名作前缀,有时这样显得很麻烦。因此,SQL允许在FROM短语中为关系名定义别名,格式为:<关系名><别名>39\n比如:如下的联接语句是一个基于4个关系的联接查询,其中必须使用关系名作前缀;SELECT供应商FROM供应商,订购单,职工,仓库;WHERE地址=”北京”AND城市=”北京”;AND供应商.供应商号=订购单.供应商号;AND订购单.职工号=职工.职工号;AND职工.仓库号=仓库.仓库号40\n在上面的查询中,如果使用别名就会简单一些,如下是使用了别名的同样的联接查询语句。SELECT供应商FROM供应商S,订购单P,职工E,仓库W;WHERE地址=”北京”AND城市=”北京”;ANDS.供应商号=P.供应商号;ANDP.职工号=E.职工号;ANDE.仓库号=W.仓库号41\n在这个例子中,别名并不必须的,但是在关系的自联接操作中,别名就是必不可少的了。SQL不仅可以对多个关系实行联接操作,也可以将同一关系与其自身进行联接,这种联接就称为自联接。在可以进行这种自联接操作的关系上,实际存在着一种特殊的递归联系,即关系中的一些元组,根据出自同一值域的两个不同的属性,可以与另外一些元组有一种对应关系(一对多的联系)。42\n例:雇员关系(雇员号,雇号姓名,经理)其中雇员号和经理两个属性出自同一个值域,同一元组的这两个属性是“上、下级”关系。43\n雇员号雇员姓名经理44\n雇员号雇员姓名经理E3赵涌E3E4钱潮E3E6孙洁E6E8李咏经理45\n雇员号雇员姓名雇员姓名经理E3赵涌赵涌E3E4钱潮钱潮E3E6孙洁孙洁E6E8李咏李咏经理46\n例:根据雇员关系列出上一级经理及其所领导的职员清单SELECTs.雇员姓名,“领导”,e.雇员姓名FROM雇员s,雇员e;WHEREs.雇员号=e.经理这里通过定义别名形成了两个逻辑关系,一个是经理关系S,一个是雇员关系E,结果在关系S和E上的联接实现了检索要求。另外,在SELECT短语中可以有变量,如这里的“领导”。47\n内外层互相关嵌套查询上面讨论的嵌套查询都是外层查询依赖于内层查询的结果,而内层查询与外层查询无关。事实上,有时也需要内、外层互相关的查询,这里内层查询的条件需要外层查询提供值,而外层查询的条件需要内层查询的结果。48\n例:在订购单表中加入一个新字段总金额,说明完成该订购单所应付出的总金额数。1、列出每个职工经手的具有最高总金额的订购单信息。SELECTout.职工号,out.供应商号,out.订购单号,out.订购日期,out.总金额;FROM订购单outWHERE总金额=;(SELECTMAX(总金额)FROM订购单inner1;WHEREout.职工号=inner1.职工号)49\n在这个查询中,外层查询和内层查询使用同一个关系,给它们分别指定别名out和inner1。外层查询提供out关系中每个元组的职工号值给内层查询使用;内层查询利用这个职工号值,确定该职工经手的具有最高总金额的订购单的总金额;随后外层查询再根据out关系的同一元组的总金额值与该总金额值进行比较,如果相等,则该元组被选择。50\n使用量词和谓词的查询<表达式><比较运算符>[ANY|ALL|SOME](子查询)[NOT]EXISTS(子查询)ANY、ALL和SOME是量词,其中ANY和SOME是同义词,在进行比较运算时只要子查询中有一行能使结果为真,则结果就为真;而ALL则要求子查询中的所有行都使结果为真时,结果才为真。EXISTS是谓词,EXISTS或NOTEXISTS是用来检查在子查询中是否有结果返回,即存在元组或不存在元组。51\n例:1、检索那些仓库中还没有职工的仓库的信息。这里的查询是没有职工或不存在职工,所以可以使用谓词NOTEXISTS:SELECT*FROM仓库WHERENOTEXISTS;(SELECT*FROM职工表WHERE仓库.仓库号=职工表.仓库号)52\n注:这里的内层查询引用了外层查询的表,只有这样使用谓词EXISTS或NOTEXISTS才有意义。所以这类查询也都是内、外层互相关嵌套查询。以上的查询等价于:SELECT*FROM仓库WHERE仓库号NOTIN;(SELECT仓库号FROM职工表)53\n2、检索哪些仓库中至少已经有一个职工的仓库的信息。SELECT*FROM仓库WHEREEXISTS;(SELECT*FROM职工表WHERE仓库号=仓库.仓库号)它等价于:SELECT*FROM仓库WHERE仓库号IN;(SELECT仓库号FROM职工表)注:[NOT]EXISTS只是判断子查询中是否有或没有结果返回,它本身并没有任何运算或比较。54\n3、检索有职工的工资大于或等于wh1仓库中任何一名职工工资的仓库号。这个查询可以使用ANY或SOME量词。SELECTDISTINCT仓库号FROM职工表WHERE工资>=ANY;(SELECT*FROM职工表WHERE仓库号=”wh1”)它等价于:SELECTDISTINCT仓库号FROM职工表WHERE工资>=;(SELECTMIN(工资)FROM职工表WHERE仓库号=”wh1”)55\n4、检索有职工的工资大于或等于wh1仓库中所有职工工资的仓库号。这个查询可以使用ALL量词。SELECTDISTINCT仓库号FROM职工表WHERE工资>=ALL;(SELECT*FROM职工表WHERE仓库号=”wh1”)它等价于:SELECTDISTINCT仓库号FROM职工表WHERE工资>=;(SELECTMAX(工资)FROM职工表WHERE仓库号=”wh1”)56\n§5.2.12超联接查询超联接:首先保证一个表中满足条件的元组都在结果表中;然后将满足联接条件的元组与另一个表的元组进行联接,不满足联接条件的则将应来自另一表的属性值置为空值。内部联接左联接右联接全联接57\n内部联接:只有满足联接条件的记录才出现在查询结果中。58\n左联接:即除满足联接条件的记录出现在查询结果中外,第一个表中不满足联接条件的记录也出现在查询结果中。59\n右联接:即除满足联接条件的记录出现在查询结果中外,第二个表中不满足联接条件的记录也出现在查询结果中。60\n全联接:除满足条件的记录出现,两表中不满足联系条件的记录也出现在查询结果中。61\n格式:SELECT……FROMTableINNER|LEFT|RIGHT|FULLJoinTableONJoinConditionWHERE……62\n例1:内部联接。Select仓库.仓库号,城市,面积,职工号,工资;from仓库innerjoin职工;on仓库.仓库号=职工.仓库号例2:左联接。Select仓库.仓库号,城市,面积,职工号,工资;from仓库leftjoin职工;on仓库.仓库号=职工.仓库号63\n例3:右联接。Select职工.仓库号,城市,面积,职工号,工资;from仓库rightjoin职工;on仓库.仓库号=职工.仓库号例4:全联接。Select仓库.仓库号,职工.仓库号,城市,面积,职工号,工资;from仓库fulljoin职工;on仓库.仓库号=职工.仓库号64\n例5:多表联接。找出供应商所在城市及其供货的仓库所在的城市。SELECT仓库.仓库号,城市,供应商名,地址;FROM供应商JOIN订购单JOIN职工JOIN仓库;ON职工.仓库号=仓库.仓库号;ON订购单.职工号=职工.职工号;ON供应商.供应商号=订购单.供应商号注:JOIN的顺序和ON的顺序正好相反。65\n练习:1.查找每个职工的订购单及订单的供应商名,结果按职工号升序排列(左联)。2.显示每个学生所先修的课程名及成绩。66\n解答:1.select职工号,订购单号,订购单.供应商号,供应商名;from订购单leftjoin供应商;on订购单.供应商号=供应商.供应商号orderby职工号2.select学生.学号,姓名,课程名,成绩from学生;join成绩join课程on成绩.课程号=课程.课程号;on学生.学号=成绩.学号67\n知识点总结:1.基本概念:超联接、内部联接、左联接、右联接、全联接2.学会使用SQL超联接查询语句。68\n集合的并运算SQL支持集合的并(UNION)运算,即可以将两个SELECT语句的查询结果通过并运算全并成一个查询结果。为了进行并运算,要求这样的两个查询结果具有相同的字段个数,并且对应字段的值要出自同一个值域,即具有相同的数据类型和取值范围。例:以下语句的结果是城市以北京和上海的仓库信息;SELECT*FROM仓库WHERE城市=”北京”;UNION;SELECT*FROM仓库WHERE城市=”上海”69\n特殊查询1.显示部分结果TOPnExpr[PERCENT]其中nExpr是数字表达式,当不使用PERCENT时,nExpr是1至32767间的整数,说明显示前几个记录;当使用PERCENT时,nExpr是0.01至99.99间的实数,说明显示结果中前百分之几的记录。注意:TOP短语要与ORDERBY短语同时使用才有效。70\n1、查询工资最高的三位职工的信息SELECT*TOP3FROM职工表ORDERBY工资DESC2、显示工资最低的那30%职工的信息SELECT*TOP30PERCENTFROM职工表ORDERBY职工71\n查询结果去向1、将查询结果存放到数组中INTOARRAYArrayName一般存放查询结果的数组作为二维数组来使用,每行一条记录,每列对应于查询结果的一列。查询结果存放在数组中,可以非常方便地在程序中使用。将查询到的职工信息存放在数组tmp中SELECT*FROM职工表INTOARRAYtmp72\n2、将查询结果存放在临时文件中INTOCURSOR临时文件名该命令产生的临时文件是一个只读的dbf文件,当查询结束后该临时文件是当前文件,可以像一般的dbf文件一样使用,但仅是只读。当关闭文件时该文件将自动删除。73\n例:将查询到的职工信息存放在临时dbf文件tmp中SELECT*FROM职工表INTOCURSORtmp注:一般利用INTOCURSOR短语存放一些临时结果,如一些复杂的汇总可能需要分阶段完成,需要根据几个中间结果再汇总等,利用该短存放中间结果就非常合适,当使用完后这些临时文件会自动删除。74\n3、将查询结果存放到永久表中INTODBF|TABLE文件名SELECT*TOP3FROM职工表INTOTABLEhighsalORDERBY工资DESC4、将查询结果存放到文本文件中TOFILE文本文件名[ADDITIVE]将查询结果存放到文本文件中,扩展名是.txt,如果使用ADDITIVE结果将追加在原文件的尾部,否则将覆盖原有文件。75\n例:将上例查询结果以文本的形式存储在文本文件tmp.txt中SELECT*FROM职工表TOtmpWHERE工资>50076\n5、将查询结果直接输出到打印机TOPRINTER[PROMPT]可直接将查询结果输出到打印机,若使用了PROMPT选项,在开始打印之前会打开打印机设置对话框。注:若在同一个查询中同时包括了INTO和TO子句,则TO子句不起作用。77\nSQL的操作功能:插入、更新、删除1、添加数据格式一:INSERTINTO<<表名>[(<字段名1>[,<字段名2>[,…]])]VALUES(<表达式1>,[,<表达式2>[,…]])格式二:INSERTINTO表名FROMARRAY数组名|FROMMEMVAR78\n格式一:是向指定的表中插入记录,当插入的不是完整的记录时,可以指定字段。VALUES用来给出具体的记录值格式二:FROMARRAY说明从指定的数组中插入记录值,FROMMEMVAR说明根据同名的内存变量来插入记录值,如果同名的变量不存在,那么相应的字段为默认值或空。例:往订购单关系中插入元组(”e7”,”s4”,”or01”,2001/05/25)79\n可用如下命令:INSERTINTO订购单VALUES(”e7”,”s4”,”or01”,{^2001/05/25})其中,{^2001/05/25}是日期型字段订购日期的值,请注意这里日期型数据的表示方式。对以上情况,假设供应商尚未确定,那么只能先插入职工号和订购单 两个属性的值,这里可用以下命令:INSERTINTO订购单(职工号,订购单号)VALUES(”e7”,”or01”)用以上语句是对某些属性进行插入,这里另外两个属性的值为空。80\n注:当一个表定义了主索引或候选索引后,由于相应的字段具有关键字的特性,即不能为空,所以只能用此命令插入记录。VF以前的插入命令(INSER或APPEND)是先插入一条空记录,然后再输入各字段的值,由于关键字字段不允许为空,所以使用以前的方法就不能成功地插入记录。81\n2.更新UPDATE<表名>SET<列名>=表达式……[WHERE<条件>];82\n一般使用WHERE子句指定条件,以更新满足条件的一些记录的字段值,并且一次可以更新多个字段,如果不使用WHERE子句,则更新全部记录。例如:给wh1仓库的职工提高10%的工资,可以用如下命令。UPDATE职工表SET工资=工资*1.1;WHERE仓库号=”wh1”又如:给所有学生的成绩加1分;UPDATE学生SET成绩=成绩+183\n3.删除DELETEFROM<表名>[WHERE<条件>]FROM指定从哪个表中删除数据,WHERE指定被删除的记录所满足的条件,若不使用WHERE子句,则删除该表中的全部记录.例:要删除仓库关系中仓库号值是wh2的元组,可用命令:DELETEFROM仓库WHERE仓库号=”wh2”注:在VF中SQLDELETE命令同样是逻辑删除记录,如果要物理删除记录需要继续使用PACK命令。84\n定义功能1、表的定义定义表名CREATETABLE|DBF表名[NAME长表名][FREE]定义字段(字段1字段类型[(字段宽度),[字段精度]]是否允许空值[NULL|NOTNULL](默认允许空值)实体完整性[PRIMARYKEY|UNIQUE][REFERENCES表名2[TAG索引文件名]]85\n域完整性[CHECK[表达式]]出错提示信息[ERROR[提示信息]]定义默认值[DEFAULT[表达式]][字段2字段类型[(字段宽度),[字段精度]]同上…|FROMARRAY数组名86\n从以上句法格式可以看出来,用CREATETABLE命令建立表可以完成用第四章介绍的表设计嚣完成的所有功能。除了建立表的基本功能外,它还包括满足实体完整性的主关键字(主索引)PRIMARYKEY、定义域完整性CHECK约束及出错提示信息ERROR、定义默认值的DEFAULT等。另外还有描述表之间联系的FOREIGNKEY和REFERENCES等。87\n下表中列出了在CREATETABLE命令中可以使用的数据类型及明,这些数据类型在第三章已做了详细说明。88\n例:用命令建立订货管理1数据库。CREATEDATABASE订货管理1用SQLCREATE命令建立仓库1表:CREATETABLE仓库1(;仓库号C(5)PRIMARYKEY,城市C(10),;面积ICHECK(面积>0)ERROR“面积应该大于0!”)89\n这里用TABLE和DBF是等价的,前者是标准SQL关键词,后者是VF的关键词;如上命令在当前打开的订货管理1数据库中建立了仓库1表,其中仓库号是主关键字(主索引,用PRIMARYKEY说明),用CHECK为面积字段值说明了有效性规则(面积>0),用ERROR为该有效性规则 说明了出错提示信息“面积应该大于0!”。如果订货管理1数据库设计器没有打开,可以用MODIFYDATABASE命令打开,那么执行完如上命令后在数据库设计器中立刻可以看到该表。90\n例:用SQLCREATE命令建立职工1表。CREATETABLE职工1(;仓库号C(5),;职工号C(5)PRIMARYKEY,;工资ICHECK(工资>1000AND工资<=5000);ERROR“工资值的范围在1000~5000!”DEFAULT1200,;FOREIGNKEY仓库号TAG仓库号REFERENCES仓库1)91\n以上命令除了用PRIMARYKEY说明了主关键字,用CHECK说明了有效性规则,用ERROR说明了出错信息之外,还用DEFAULT为工资字段值说明了默认值(1200)。用短语“FOREIGHKEY仓库号TAG仓库号REFERENCES仓库1”说明了职工1表与仓库1表的联系;用“FOREIGHKEY仓库号”在该表的仓库号字段上建立一个普通索引,同时说明该字段是联接字段,通过引用仓库1的主索引“仓库号”(TAG仓库号REFERENCES仓库1)与仓库1建立联系。92\n例:用SQLCREATE命令建立供应商1表。CREATETABLE供应商1(;供应商号C(5)PRIMARYKEY,供应商名C(20),地C(20))用SQLCREATE建立订购单1表。CREATETABLE订购单1(;职工号C(5),;供应商号C(5),;订购单号C(5)PRIMARYKEY,;订购日期D,;FOREIGNKEY职工号TAG职工号REFERENCES;职工1,FOREIGNKEY供应商号TAG供应商号;REFERENCES供应商1)93\n以上命令有两个FOREIGNKEY…REFERENCES短语,分别说明了订购单1表与职工1表、订购单1表与2供应商1表之间的联系。94\n注:用SQLCREATE命令新建的表自动在最低可用工作区打开,并可以通过别名引用,新表的打开方式为独占方式,忽略SETEXCLUSIVE的当前设置。95\n2.表的删除DROPTABLE<表名>作用:可直接从磁盘上删除.dbf表文件.若表名是数据库中的表并且相应的数据库是当前数据库,则从数据库中删除了表;否则虽然从磁盘上删除了dbf文件,但是记录在数据库dbc文件中的信息却没有删除,此后会出现错误提示.所以要删除数据库中的表时,最好应使数据库是当前打开的数据库,在数据库中进行操作.96\n3.表结构的修改格式一:ALTERTABLE表名ADD|ALTER[COLUMN]字段1字段类型[(字段宽度),[字段精度]][NULL|NOTNULL](默认允许空值)[CHECK字段1[ERROR[提示信息]][DEFAULT[表达式]][PRIMARYKEY|UNIQUE][REFERENCES表名2[TAG索引文件名1]]97\n该命令格式可以添加(ADD)新的字段或修改(ALTER)已有的字段,它的句法基本可以与CREATETABLE的语句相对应。98\n例1、为订购单1表增加一个货币类型的总金额字段。ALTERTABLE订购单1ADD总金额YCHECK总金额>0ERROR“总金额应该大于0!”99\n2、将订购单1表的订购单号字段的宽度由原来的5改为6。ALTERTABLE订购单1ALTER订购单号C(6)从命令格式可以看出,该格式可以修改字段的类型、宽度、有效性规则、错误信息、默认值,定义主关键字和联系等;但是不能修改字段名,不能删除字段,也不能删除已经定义的规则等。100\n格式二:ALTERTABLE表名ALTER[COLUMN]字段1[NULL|NOTNULL][SETDEFAULT[表达式1]][SETCHECK表达式2[ERROR[提示信息]][DROPDEFAULT][DROPCHECK]从命令格式可以看出,该格式主要用于定义、修改和删除有效性规则和默认值定义。101\n例:1、修改或定义总金额字段的有效性规则。ALTERTABLE订购单1ALTER总金额SETCHECK总金额>100ERROR“总金额应该大于100!”102\n2、删除总金额字段的有效性规则。ALTERTABLE订购单1ALTER总金额DROPCHECK以上两格式都不能删除字段,也不能更改字段名,所有修改是在字段一级。第三种格式正是在这些方面对前两种格式的补充。103\n格式三:ALTERTABLE表名1[DROP[COLUMN]字段1[SETDEFAULT[表达式1]][ERROR[提示信息]][DROPCHECK][ADDPRIMARYKEY表达式TAG索引名][FOR条件][DROPPRIMARYKEY][ADDUNIQUE表达式[TAG索引名][FOR条件]][DROPUNIQUETAG索引名][ADDFOREIGNKEY[表达式][TAG索引名][FOR条件]]REFERENCES表名2[TAG索引名]DROPFOREIGNKEYTAG索引名[RENAMECOLUMN字段名TO新字段名]104\n该格式可以删除字段(DROP[COLUMN]、可以修改字段名(RENAMECOLUMN)、可以定义、修改和删除表一级的有效性规则等。105\n例:1、将订购单1表的总金额字段名改为金额。ALTERTABLE订购单1RENAMECOLUMN总金额TO金额2、删除订购单1表中的金额字段。ALTERTABLE订购单1DROPCOLUMN金额3、将订购单1表的职工号和供应商号定义为候选索引(候选关键字),索引名是emp_sup。TABLE订购单1ADDUNIQUE职工号+供应商号TAGemp_sup106\n4、删除订购单1表的候选索引emp_supALTERTABLE订购单1DROPUNIQUETAGemp_sup107\n视图的定义在VF中视图是一个定制的虚拟表,可以是本地的、远程的或带参数的。视图可引用一个或多个表,或者引用其他视图。视图是可更新的,它可引用远程表。在关系数据库中,视图也称作窗口,即视图是操作表的窗口,可以把它看作是从表中派生出来的虚表。它依赖于表,但不独立存在108\n视图是根据对表的查询定义的,其命令格式如下:CREATEVIEW视图名[(字段名1[,字段名2]…)]ASselect_statement其中select_statement可以是任意的SELECT查询语句,它说明和限定了视图中的数据;当没有为视图指定字段名时,视图的字段名将与select_statement中指定的字段名或表中的字段名同名。视图是根据表定义或派生出来的,所以在涉及到视图的时候,常把表称作基本表。109\n1、从单个表派生出的视图比如:某个用户对职工关系只需要,或者只能知道职工号和所工作的仓库号,那么可以定义视图:CREATEVIEWe_wAS;SELECT职工号,仓库号FROM职工表其中e_w是视图的名称。视图一经定义,就可以和基本表一样进行各种查询,也可以进行一些修改操作。对于最终用户来说,有时并不需要知道操作的是基本表还是视图。为了查询职工号和仓库号信息,可以有命令:110\nSELECT*FROMe_w或SELECT职工号,仓库号FROMe_w或SELECT职工号,仓库号FROM职工表以上的语句可以收到同样的效果。111\n上面是限定列构成的视图,下面再限定行定义一个视图。比如:某个用户对仓库关系只需要,或者只能查询北京仓库的信息,可以定义如下视图:CREATEVIEWv_bjAS;SELECT仓库号,面积FROM仓库WHERE城市=”北京”这里v_bj中只有北京仓库的信息,所以城市属性就不需要了。112\n2、从多个表派生出的视图从上面的例子可以看出,视图一方面可以限定对数据的访问,另一方面又可以简化对数据的访问。在前面查询的例子中,有些查询是很复杂的,比如:列出每个职工经手的具有最高总金额的订购单信息。如果要求部门的经理也键入这么复杂的命令,实在有点太强求了。有一种替代的方法,那就是视图:113\nCREATEVIEWv_sampleAS;SELECTout.职工号,out.供应商号,out.订购单号,out.订购日期,out.总金额;FROM订购单outWHERE总金额=;(SELECTMAX(总金额)FROM订购单inner1;WHEREout.职工号=inner1.职工号)114\n这时候再提出同样的查询要求,就只需要输入以下命令即可:SELECT*FROMv_sample从以上可以看出,如果技术人员能按照用户的业务需求定义出这样的视图,对最终用户就实在太方便了。115\n3、视图中的虚字段。用一个查询来建立一个视图的SELECT子句可以包含算术表达式或函数,这些表达式或函数与视图的其他字段一样对待,由于它们是计算得来的,并不存储在表内,所以称为虚字段。116\n例:定义一个视图,它包含职工号、月工资和年工资3个字段。CREATEVIEWv_salAS;SELECT职工号,工资AS月工资,;工资*12AS年工资FROM职工表117\n这里在SELECT短语中利用AS重新定义了视图的字段名。由于其中一字段是计算得来的,所以必须给出字段名。这里年工资是虚字段,它是由职工表的工资字段乘以12得到的;而月工资就是职工表中的工资字段,由此可见,在视图中还可以重新命名字段名。SELECT*FROMv_sal118\n4、视图的删除视图由于是从表中派生出来的,所以不存在修改结构的问题,但是视图可以删除。在VF中可以修改视图,我们将在第六章中介绍。删除视图的命令格式是:DROPVIEW<视图名>比如要删除视图v_sal,只要键入命令:DROPVIEWv_sal119\n5、关于视图的说明在VF中视图是可更新的,但是这种更新是否反映在基本表中则取决于视图更新属性的设置。在VF中视图有它特殊的概念和用途。120\n在关系数据库中,视图始终不真正含有数据,它总是原来表的一个窗口。所以,虽然视图可以像表一样进行各种查询,但是插入、更新和删除操作在视图上却有一定限制。当一个视图是由单个表导出时可以进行插入和更新操作,但不能进行删除操作;当视图是从多个表导出时,插入、更新和删除操作都不允许进行。这种限制是很有必要的,它可以避免一些潜在问题的发生。121\n演示完毕,谢谢观看!122\n此课件下载可自行编辑修改,供参考!感谢您的支持,我们努力做得更好!