SQL语言初步

  
SQL 语言初步
1 、SQL 的基本概念
SQL支持数据库的三级模式结构,模式与基本表相对应,外模式与视图相对应,内模式对应于存储文件。基本表和视图都是关系。
(1 )基本表(BaseTable
基本表是模式的基本内容。每个基本表都是一个实际存在的关系。
(2 )视图(View
视图是外模式的基本单位,用户通过视图使用数据库中基于基本表的数据(基本表也可作为外模式使用)。一个视图虽然也是一个关系,但是它与基本表有着本质的区别。任何一个视图都是从已有的若干关系导出的关系,它只是逻辑上的定义,实际并不存在。在导出时,给出一个视图的定义(从哪几个关系中,根据什么标准选取数据,组成一个什么名称的关系等),此定义存放在数据库(数据字典)中,但没有真正执行此定义(并未真正生成此关系)。
当使用某一视图查询时,将实时从数据字典中调出此视图的定义;根据此定义以及现场查询条件,从规定的若干基本表中取出数据,组织成查询结果,展现给用户。因此,视图是虚表,实际并不存在,只有定义存放在数据字典中。当然,用户可在视图上再定义视图,就像在基本表上定义视图一样,因为视图也是关系。因而对于用户来说,使用一个视图和使用一个基本表的感觉是一样的。只是对视图进行修改时,有时会产生一些麻烦
(3 )存储文件
存储文件是内模式的基本单位。每一个存储文件存储一个或多个基本表的内容。一个基本表可有若干索引,索引也存储在存储文件中。存储文件的存储结构对用户是透明的。
(4 )SQL 语句分类
SQL命令核心功能主要有以下几类:
数据定义语言(DateDefinitionLanguage:DDL):负责创建、修改、删除表、索引和视图等对象,由动词Create、Alter、Drop组成。
数据操作语言(DateManegementLanguage:DML):负责数据库中数据的插入、修改、查询和删除操作,由动词Select、Insert、Delete和Update组成。
数据控制语言(DateControlLanguage:DCL):用来授予和撤销用户对数据的操作权限。主要由动词Grant和Revork组成。
2 、基本的数据定义
2.1 、创建基本表——CREATE TABLE
(1)语句基本格式
    CREATE TABLE <表名>
    (<列定义清单>);
(2)说明
1)<表名>:规定所创建的基本表的名称。在一个数据库中,不允许有两个基本表同名
2)<列定义清单 >:规定了该表中所有属性列的结构情况。每一列的内容最少包括:
   <列名> <数据类型>[<该列的完整性约束>]
两列内容之间用西文逗号隔开。
3)<列名>:规定了该列(属性)的名称。一个表中不能有两列同名。
4)<数据类型>:规定了该列的数据类型。
5)<该列的完整性约束>:该列上数据必须符合的条件。
2.2 、表结构的修改——ALTER TABLE
基本表的结构是会随环境的变化而修改的,即根据需要增加、修改或删除其中一列(或完整性约束条件,增加或删除表级完整性约束等)。
(1)语句格式
    ALTER TABLE <表名>
    [ADD <列名> <数据类型>[列的完整性约束]]
    [DROPCOLUMN <列名>]
    [MODIFY <列名> <新的数据类型>]
    [ADD CONSTRAINT <表级完整性约束>]
    [DROPCONSTAINT <表级完整性约束>];
(2)说明
1)ADD:为表增加一新列,具体规定与CREATE TABLE的相当,但新列必须允许为空(除非有默认值);
2)DROPCOLUMN:在表中删除一个原有的列;
3)MODIFY:修改表中原有列的数据类型;通常,当该列上有约束定义时,不能修改数据类型。
4)ADD CONSTRAINT:增加表级约束;
5)DROPCONSTAINT:删除原有的表级约束。
2.3 、删除基本表——DROP TABLE < 表名>
(1)语句格式
    DROPTABLE <表名>
(2)说明
此语句一执行,指定的表即从数据库中删除(表被删除,表在数据字典中的定义也被删除),此表上建立的索引和视图也被自动删除
2.4 、建立索引——CREATE INDEX
在一个基本表上,可建立若干索引。有了索引,可以加快查询速度。索引的建立和删除工作由DBA或表的属主(拥有者)负责。用户在查询时并不能选择索引,选择索引的工作由DBMS自动进行。
(1)语句格式
   CREATE [UNIQUE][CLUSTER]INDEX <索引名>
   ON <表名>(<列名清单>)
本语句为规定<表名>建立一索引,索引名为<索引名>。
(2)说明
1)<列名清单>中,每个列名后都要指定 ASC(升序)或DESC(降序)。若不指定,默认为升序。
2)本语句建立索引的排列方式为:首先以<列名清单>中的第一个列的值排序;该列值相同的记录,按下一列名的值排序;以此类推。
3)UNIQUE:规定索引的每一个索引值只对应于表中唯一的记录。
4)CLUSTER:规定此索引为聚簇索引。一个表最多只能有一个聚簇索引。建立聚簇索引后,表在磁盘中的物理存储顺序将与聚簇索引中的一致。在最常查询的列上建立聚簇索引可以加快查询速度;在经常更新的列上建立聚簇索引,则 DBMS维护索引的代价太大。 2.5 、删除索引——DROP INDEX
索引太多,索引的维护开销也将增大。因此,不必要的索引应及时删除。
(1)语句格式
    DROP INDEX <表名>.<索引名>
(2)说明本语句将删除规定的索引。该索引在数据字典中的描述也将被删除。
3 、基本的数据操纵
3.1 、表中增加元组的基本方法——INSERT
NSERT语句既可以为表插入一条记录,也可一次插入一组纪录。
(1)语句格式
    INSERT INTO <表名>[(<属性名清单>)]
VALUS(<常量清单>);
本语句在指定表中插入一条新记录。
(2)说明
1)若有<属性名清单>,则<常量清单>中各常量为新记录中这些属性的对应值。但该表定义时,说明为NOT NULL,且无默认值的列必须出现在<属性名清单>中,否则将出错。   
2)如无<属性名清单>,则<常量清单>必须按照表中属性的顺序,为每个属性列赋值 3.2 、修改表中数据的基本方法——UPDATE
要修改表中已有记录的数据时,可用UPDATE语句。
(1)语句格式
    UPDATE <表名>
    SET <列名> = <表达式> [,<列名> = <表达式>]
   [WHERE <条件>];
本语句把指定<表名>内,符合<条件>记录中规定<列名>的值更新为该<列名>后<表达式>的值。
(2)说明
若无WHERE<条件>项,则修改全部记录。
3.3 、删除记录——DELETE
有时需要删去一些记录,则可用DELETE语句。
(1)语句格式
    DELETE FROM <表名>
   [WHERE<条件>]
本语句将在指定<表名>中删除所有符合<条件>的记录。
(2)说明
当无WHERE<条件>项时,将删除<表名>中的所有记录。但是,该表的结构还在(包括属性、约束等),只是没有了记录,是个空表而已。
4 、数据查询——SELECT 语句
查询是数据库应用的核心内容。使用SELECT语句时,用户不需指明被查询关系的路径,只需要指出关系名,查询什么,有何附加条件即可。
SELECT既可以在基本表关系上查询,也可以在视图关系上查询。
4.1 、单关系无条件查询
单关系查询涉及一个关系的所有列或者几个列。
(1)单关系无条件查询的基本格式
    SELECT[DISTINCT/ALL]<目标列表达式[[AS]别名]清单>
    FROM <关系名>;
本语句从当前数据库中找到指定的关系,取出选中的列到结果集中。
(2)说明
1)[DISTINCT/ALL]:若从一关系中查询出符合条件的元组,但输出部分属性值,结果关系中就可能有重复元组存在。选择DISTINCT,则每组重复元组只输出一条元组;选择ALL,则所有重复元组全部输出。两个都不选,默认为ALL。
2)<目标列表达式>:一般地,每个目标列表达式本身将作为结果关系列名,表达式的值作为结果关系中该列的值。
3)FROM <关系名>:指明被查询的关系名。
SQL显示查询结果时,使用属性名作为列标题。属性名通常很短并且令人费解。要改变这些列标题以便更好地让用户理解,可以为列标题设置别名。
SELECT的目标列表达式中,除了可以是表的属性名、计算表达式、常量外,还可以是集函数。
为了增强查询功能,SQL提供了许多集函数:
    COUNT([DISTINCT/ALL]*)        统计表中的元组个数
    COUNT([DISTINCT/ALL]<列名>)  统计一列上值的个数
    MAX(<列名>)                      给出一列上的最大值
    MIN(<列名>)                      给出一列上的最小值
    SUM([DISTINCT/ALL]<列名>)     给出一列上值的总和(只对数值型)
    AVG([DISTINCT/ALL]<列名>)     给出一列上值的平均值(只对数值型)
例如:
    SELECT count(*)FROM employee         得到employee表的记录数
    SELECT count(title) FROM employee      得到职称的个数
   SELECT count(distincttitle)FROM employee 得到职称的种类数
求所有项目的总经费、平均经费、最高经费和最低经费。
    SELECT sum(outlay)AS总经费,avg(outlay)AS平均经费,
     max(outlay)AS最高经费,min(outlay)AS最低经费
    FROM item
4.2 、单关系有条件查询
(1)单关系条件查询的基本格式
    SELECT[DISTINCT/ALL]<目标列表达式[别名]清单>
    FROM <关系名>
    WHERE <查询条件表达式>;
本语句从当前数据库中找到指定的关系,找出符合 WHERE子句中 <查询条件表达式>的元组;再根据<目标列表达式清单>的规定,组合这些元组的属性值,形成一个新的查询结果关系;最后输出这个结果关系。
(2)说明WHERE<查询条件表达式>:给出查询条件。WHERE子句中不能用集函数作为条件表达式。
根据查询条件的不同,单表条件查询又可以分为以下几种:
1)使用比较运算符使用比较运算符的条件表达式的一般形式为:
    <属性名>@<属性名>,<属性名>@常量
其中@为比较操作符 =、<、>、< =、> =、< > 等。
2)使用特殊运算符
ANSI标准SQL允许WHERE子句中使用特殊的运算符
特殊运算符号运算符号含义:
IN、NOT IN:检查属性值是否属于一组值之一
BETWEEN…AND…、NOT BETWEEN…AND…:检查属性值是否属于某个范围
IS NULL、IS NOT NULL:检查属性值是否为空
LIKE、NOT LIKE:字符串匹配
特殊符号LIKE可用来进行字符串的匹配,其一般格式为:
    [NOT]LIKE ′<匹配字符串>′[ESCAPE ′<转义字符>′]
其中,匹配串是一个字符串,可以包含有通配符“%”和“-”。“% ”表示任意长度的字符串(长度可为0);“-”表示任意单个字符。
若通配符本身就是要匹配的字符串内容,则可增加短语ESCAPE,使之转义。
如:WHERE InameLIKE ′C/-% ′ESCAPE ′/′,则紧跟在/后的-不是通配符,仅是一个字符而已。该查询条件为:Iname属性值以字符“C-”开头,后可跟任意个字符。
3)多条件单关系查询
当需要查询满足多个条件的数据时,WHERE子句中的<查询条件表达式>可以辅以布尔运算符,如 NOT、AND 和 OR 进行检索。其一般形式是:
    <条件表达式>[AND|OR<条件表达式>]
其中,各<条件表达式>本身为逻辑值(真或假)。
4.3 、分组查询
有时需要将查询结果分组输出,这时可在Select语句中使用Group By子句。
(1)分组查询的基本格式
    SELECT[DISTINCT/ALL]<目标列表达式[别名]清单>
    FROM <关系名>
   [WHERE <查询条件表达式>]
    GROUPBY < 列名清单>[HAVING <条件表达式>];
(2)说明GROUP BY子句把查询所得元组根据GROUP BY中<列名清单>的值进行分组。在这些列上,对应值都相同的元组分在同一组;若无 HAVING 子句,则各组分别输出;若有HAVING子句,只有符合HAVING条件的组才输出。此时,SELECT子句中,只能包含两种目标列表达式:要么是集函数,要么是出现在GROUP BY后面的分组字段。
一般地,当SELECT的<目标列表达式[别名]清单>中有集函数(COUNT、SUM 等)时,才使用GROUPBY子句。
例 把职工表中元组按部门分组,计算平均年龄;输出部门号和平均年龄两列。
SELECT Dno,AVG(Age)AS Average-Age
FROM Employee
GROUPBY Dno;
结果如下:
Dno         Average-Age
01          36
02          33
03          43
有了GROUP BY子句后,AVG函数对每一组求平均值,若无GROUP BY,AVG对整个输出求平均。GROUP BY子句细化了集函数的作用对象。这一点对所有的集函数都成立。
例 加上Having条件,语句改为:
SELECT Dno,AVG(Age)AS Average-Age
FROM Employee
GROUP BY Dno
HAVING AVG(Age)< 40;
则输出结果为:
Dno       Average-Age
01        36
02        33
HAVING条件作用于结果组,选择满足条件的结果组。而WHERE条件作用于被查询的关系,从中选择满足条件的元组。
4.4 、排序查询结果
SELECT语句的ORDER BY子句可使输出结果按照要求的顺序排列。
(1)排序查询结果的基本格式
 SELECT[DISTINCT/ALL]<目标列表达式[别名]清单>
 FROM <关系名>
[WHERE <查询条件表达式>]
[GROUPBY <列名清单>[HAVING <条件表达式>]]
 ORDER BY <列名[ASC/DESC]清单>;
(2)说明
有了ORDER BY子句后,SELECT语句的查询结果表中各元组将排序输出:首先按第一个<列名>值排序;前一个<列名>值相同者,再按下一个<列名>值排序,以此类推。若某列名后有DESC,则以该列名值排序时为降序排列,否则,为升序排列。
ORDER BY子句只能作用于最终查询结果。
4.5 、多关系连接查询
SELECT语言可以方便地实现关系的连接查询,即实现从两个或多个关系中检索出所需要的数据。多个关系之间的连接类型有以下几种:
交叉连接(CrossJoin);
内连接(InnerJoin);
外连接(OuterJoin)。外连接又分为:
· 左外连接(LeftJoin);
· 右外连接(RightJoin);
· 全连接(FullJoin);
自身连接(SelfJoin)。
连接查询的类型可以在SELECT语句的FROM 子句中指定,也可以在其WHERE子句中指定。
(1 )交叉连接
交叉连接的一般格式为:
SELECT[DISTINCT/ALL]<目标列表达式[别名]清单>
FROM <关系名[别名]清单>需要连接查询的关系名在FROM 子句中指定,关系名之间用西文逗号分开。
例 SELECT e.Ename,e.Title,e.Dno,d.Dno,d.Name
    FROM employee e,department d
上述命令中的“e”和“d”分别是职工表和部门表的别名,此处只是为了简化表名。但是,一旦为关系名指定了别名,则在该命令中,都必须用别名代替该关系名。
把employee表与department表连接成一个新表,新表由两表各部分属性组成(见SELECT子句)。在 FROM 子句和 WHERE子句中没有指定任何连接条件,系统将employee表的每一个元组都与department表中的每一个元组进行了连接,所以最后输出的结果集中共有8×4=32个新的元组。
(2 )内连接
内部连接的一般格式为:
SELECT[DISTINCT/ALL]<目标列表达式[别名]清单>
FROM <关系名1[别名1]> INNER JOIN <关系名2[别名2]>
ON <连接条件表达式>
OR:SELECT[DISTINCT/ALL]<目标列表达式[别名]清单>
FROM <关系名[别名]清单>
WHERE <连接条件表达式>
内连接是使用最多的一种连接类型。在连接的两表中,只有满足连接条件的元组,才作为结果输出。
一般地,表和表之间的连接,是通过他们所具有的共同性质的属性实现的,连接的属性名不必相同,但数据类型要兼容。
(3 )外连接
外连接又分为左外连接、右外连接和全外连接。
左外连接:除了返回两表中满足连接条件的元组以外,还返回左侧表中不匹配元组,右侧表中以空值(NULL)替代。
右外连接:除了返回两表中满足连接条件的元组以外,还返回右侧表中不匹配元组,左侧表中以空值(NULL)替代。
全外连接:除了返回两表中满足连接条件的元组以外,还返回左侧表中不匹配元组,右侧表中以空值(NULL)替代,以及右侧表中不匹配的元组,左侧表中以空值(NULL)替代。外连接的使用格式与内连接格式相似,在使用FROM 进行连接的语句中,将 INNER JOIN改成LEFT JOIN、RIGHT JOIN或FULL JOIN。
(4 )自身连接
有时,一些特殊的查询需要对同一个关系进行连接查询,称为表的自身连接。
例 假设职工表中增加了负责人(Emgr)属性,求出所有职工号的间接负责人号。由于在employee表中只有职工的直接负责人,要找到某职工的间接负责人,必须先找到他的负责人,再按照该负责人号,找到他的负责人。这需要将employee进行自身连接。
为了把先后查询的同一关系区分开来。使用关系的别名即可达到此目的,完成该自身连接的SQL语句为:
SELECT emp1.Eno,emp2.Emgr
FROM employee emp1,employee emp2
WHERE emp1.Emgr= emp2.Eno;
此时,在SELECT子句和WHERE子句中出现的属性名,必须指明是emp1关系的还是emp2关系的。
4.6 、嵌套查询
一个SELECT FROM WHERE语句称为一个查询块,WHERE子句中的查询块称为嵌套查询。在此,外层的查询称为外层查询或父查询,内层的查询称为内层查询或子查询。
一个查询还可以再嵌套子查询,这就是多层查询,层层嵌套,这就是结构化。
求解嵌套查询的一般方法是由里向外,逐层处理。即子查询在它的父查询处理前先求解,子查询的结果作为其父查询查找条件的一部分。
(1 )使用IN 嵌套查询
例 查询所有参加了199901项目的职工号、姓名、职称。
SELECT Eno,Ename,Title
FROM Employee
WHERE Eno IN
 (SELECT Eno 
    FROM Item-emp 
    WHERE Ino= ′199901′);
本例的执行过程是,先执行子查询:
SELECT Eno
FROM Item-emp
WHERE Ino= ′199901′;
得到子查询的结果是:
   Eno
   1005
   1010
   1031
再执行父查询:
SELECT Eno,Ename,Title
FROM Employee     
WHERE EnoIN (′1005′,′1010′,′1031′);
最后得到本例的结果:
Eno       Ename      Title
1005       张小华      工程师   
1010       宋文彬      工程师
在嵌套查询中,子查询的结果常常是一个集合,所以,使用IN是嵌套查询中最常使用的连接词。
(2 )使用比较运算符的嵌套查询
比较运算符<、=、>、< =、> =、< >等,均可以作为嵌套查询的连接词。
比较运算符还可以与ANY或ALL一起使用,ANY 只要与子查询中一个值符合即可,ALL要与子查询中所有值相符合。
(3 )使用BETW EEN 的嵌套查询
[NOT]BETWEEN…AND 也可以作为嵌套查询的连接词。
(4 )相关子查询
前面的嵌套查询中,子查询都在其父查询处理前求解,它的执行不依赖于父查询的任何条件。每个子查询仅执行一次,子查询的结果集为父查询的WHERE条件所用。这类查询叫做不相关子查询。
但在有的查询中,子查询的执行依赖于父查询的某个条件,子查询不只执行一次。这类子查询的查询条件往往依赖于其父查询的某属性值,称为相关子查询。在相关子查询中,可使用EXISTS,测试子查询是否存在返回值。
4.7 、多个SELECT 语句的集合操作
SQL提供了集合并操作手段UNION,参加UNION的记录结果集必须有相同的列数,各对应项的数据类型也必须相同。
5 、含有子查询的数据更新
5.1 、INSERT 与子查询的集合
(1)格式
INSERTINTO<表名>[<属性名清单>]
(子查询);
把子查询的结果插入指定的<表名>中。这样的一条INSERT语句,可以一次插入多条元组。
5.2 、UPDATE 与子查询的结合
(1)格式
UPDATE <表名>
SET <列名> = <表达式> [,<列名> = <表达式>]
[WHERE<带有子查询的条件表达式>]
本语句执行时,将修改使<带有子查询的条件表达式>为真的所有元组。
5.3 、DELETE 与子查询的结合
(1)格式
DELETE FROM <表名>
[WHERE<带有子查询的条件表达式>]
本语句将删除所有使<带有子查询的条件表达式>为真的所有元组。
6 、视图
视图是数据库系统的一个重要机制。无论从方便用户的角度,还是从加强数据库安全的角度,视图都有着极其重要的作用。
一个视图是从一个或多个关系(基本表或已有的视图)导出的关系。导出后,数据库中只存有此视图的定义(在数据字典中),但并没有实际生成此关系。因此视图是虚表。
用户使用视图时,其感觉与使用基本表是相同的。但是
(1)由于视图是虚表,所以SQL对视图不提供建立索引的语句。
(2)SQL一般也不提供修改视图定义的语句(有此需要时,只要把原定义删除,重新定义一个新的即可,这样不影响任何数据)。
(3)对视图中数据做更新时是有些限制的。
6.1 、定义视图——CREATE VIEW
.     (1)语句格式
CREATE VIEW <视图名> [<列名清单>]
AS <子查询>     [WITH CHECK OPTION]
(2)说明
<视图名>给出所定义的视图的名称。
若有<列名清单>,则此清单给出了此视图的全部属性的属性名;否则,此视图的所有属性名即为子查询中SELECT语句中的全部目标列。
<子查询>为任一合法 SELECT语句(但一般不含有 ORDER BY,UNION 等语法成分)。
有[WITH CHECK OPTION]时,则今后对此视图进行INSERT、UQDATE和DELETE操作时,系统自动检查是否符合原定义视图子查询中的<条件表达式>。
本语句执行后,此视图的定义即进入数据字典,对语句中的<子查询>并未执行,也即视图并未真正生成。所以说,视图是虚表。
6.2 、删除视图——DROPVIEW
(1)语句格式
DROP VIEW <视图名>
此语句将把指定视图的定义从数据字典中删除。一个关系(基本表或视图)被删除后,所有由该关系导出的视图并不自动删除,它们仍在数据字典中,但已无法使用。删除视图必须用DROP VIEW 语句。
6.3 、视图的查询
(1 )用户的工作
对用户来说,对视图的查询与对基本表的查询是没有区别的,都使用SELECT语句对有关的关系进行查询工作。在查询时,用户不需区分是对基本表查询,还是对视图查询。SELECT语句中不需(也不可能)标明被查询的关系是基本表还是视图。
(2 )DBMS 对视图查询的处理
DBMS对某SELECT语句进行处理时,若发现被查询对象是视图,则 DBMS将进行下述操作:
(1)从数据字典中取出视图的定义;
(2)把视图定义的子查询和本 SELECT的查询相结合,生成等价的对基本表的查询(此过程称为视图的消解)。
(3)执行对基本表的查询,把查询结果(作为本次对视图的查询结果)向用户显示。 6.4 、视图的更新
(1 )视图更新的含义及执行过程
视图是虚表,是没有数据的。所谓视图的更新,表面上是对视图执行 INSERT、UPDATE 和 DELETE来更新视图的数据,其实质是由DBMS自动转化成对导出视图的基本表的更新,转化成对基本表的INSERT、UPDATE和DELETE语句
(2 )定义视图时,WITH CHECK OPTION 的作用
定义是根据AS<子查询>的条件定义的。但视图更新的语句 INSERT、UPDATE 和DELETE却都不能保证被更新的元组必定符合原来AS<子查询>的条件。如果这样的话,那视图就没有多大的作用了。
在定义视图时,若加上子句WITH CHECK OPTION,则在对视图更新时,系统将自动检查原定义时的条件是否满足。若不满足,则拒绝执行。
6.5 、视图的作用
视图是SQL语句支持的三级模式结构中外模式的成分。视图还有如下作用:
(1)视图能方便用户操作
(2)视图可对数据提供安全保护
(3)视图能使不同用户都能用自己喜欢的方式看待同一数据
7 、完整性约束的SQL 定义
SQL把各种完整性约束作为数据库模式定义的一部分,既可有效防止对数据库的意外破坏,提高了完整性检测的效率,又可减轻编程人员的负担。
7.1 、实体完整性和主码
在SQL中,实体完整性是通过主码(Primary Key)的定义来实现的。一旦某个属性或属性组被定义为主码,该主码的每个属性就不能为空值,并且在关系中不能出现主码值完全相同的两个元组。
主码可在定义关系的CREATE TABLE语句中使用 PRIMARY KEY 关键字加以定义。有两种定义主码的方法,一种是在属性后增加关键字,另一种是在属性表中加入额外的定义主码的子句:
PRIMARY KEY(主码属性名表)
除了主码,SQL中提供了类似于候选码的说明方法,使用关键字 UNIQUE,说明该属性(或属性组)的值不能重复出现。但说明为UNIQUE的属性可以定义为空值,与候选码又有所不同。一个表中只能有一个主码,但可以有多个“UNIQUE”说明。
7.2 、参照完整性约束和外部码
数据库模式的第二种约束类型,就是利用外部码的说明实现参照完整性约束,以限制相关表中某些属性的取值。
说明外部码的方法有两种:
1)在该属性的说明(属性名、类型)后直接加上关键字REFERENCES,后跟对应表的主码说明。格式为:
REFERENCES <父表名>(<属性名>)
其中属性名为父表的主码。
2)在CREATE TABLE语句的属性清单后,加上外部码的说明子句,格式为:
FOREIGN KEY (<属性名表>)REFERENCES <父表名>(<属性名表>)
7.3 、用户自定义完整性约束
SQL中提供了非空约束、对属性的CHECK约束、对元组的CHECK约束、触发器等来实现用户的各种完整性要求。
(1 )基于属性的CHECK 约束
使用CHECK(检查)子句可保证属性值满足某些前提条件。CHECK 子句的一般格式为:
CHECK <条件>
属性的CHECK约束既可跟在属性的定义后,也可在定义语句中另增一子句加以说明。
例 设定employee表中属性age的值不能小于18、大于65。只需将例2.49中的age属性说明为如下的形式:
age int CHECK(age> =18AND age< =65)
或在属性列表的最后加上
CHECK(age> =18AND age< =65)
(2 )基于元组的约束
对表内元组说明约束时,在CREATE TABLE语句中的属性表、主码、外部码的说明之后加上CHECK子句。每当对元组进行插入或修改操作时,都要对CHECK子句的条件表达式求值,如果条件为假,违背了约束,系统将拒绝该插入或修改操作。
例 工资表salary的定义:
CREATE TABLE salary
(Enochar(4)PRIMARY KEY,      
Basepay decimal(7,2),     
Service decimal(7,2),      
Price decimal(7,2),      
Rest decimal(7,2),      
Insure decimal(7,2),      
Fund decimal(7,2),      
CHECK(Insure+Fund<Basepay));上面例子中,CHECK约束涉及到表中多个域,为元组约束。在对整个元组完成插入或对某一元组的修改完成之后,系统将检查元组是否符合CHECK条件表达式。完
7.4 、约束的更新
约束与数据库中的表、视图等一样,可以进行增加、删除和修改的更新操作。为了修改和删除约束,需要在定义约束时对约束进行命名,在约束前加上关键字CONSTRAINT和该约束的名称。
例如要说明 employee表中的主码和外部码时,分别将其命名为 PK-employee和FK-employee:    
enochar(4)CONSTRAINT PK-employeePRIMARY KEY,    
dnochar(4)CONSTRAINT FK-employeeFOREIGN KEY REFERENCESdepartment(dno)
约束可以在定义时命名:
CONSTRAINT RightSalary
      CHECK (Insure+Fund<Basepay)这样,可以使用ALTER TABLE语句来更新与属性或表有关的约束。
例 删除employee表中的外部码约束FK-employee:
ALTER TABLE employee DROP CONSTRAINTFK-employee;
例 修改对Salary的约束RightSalary中的表达式为:
    Insure+Fund<Rest。
由于SQL不能直接修改约束,可通过以下两步完成对约束的修改:
(1)删除原约束:
ALTER TABLE Salary DROP CONSTRAINT RightSalary;
(2)增加同名约束:
ALTER TABLE Salary ADD CONSTRAINT RightSalary
    CHECK(Insure+Fund<Rest);
约束可以通过ALTER TABLE语句定义,而不一定要在表的模式定义时进行。只是通过ALTER TABLE语句定义的约束都是基于元组的约束,而不是基于属性的。
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值