第四章结构化查询语言_第1页
第四章结构化查询语言_第2页
第四章结构化查询语言_第3页
第四章结构化查询语言_第4页
第四章结构化查询语言_第5页
已阅读5页,还剩112页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第四章结构化查询语言清华大学出版社2023年1月14日数据库原理(1)

第四章结构化查询语言SQL(1)内容:教学重点:

SQL的数据查询;嵌入式SQL的使用。SQL数据库的体系结构,SQL的组成;

SQL的数据定义:SQL模式、基本表和索引的创建和撤销;

SQL的数据查询:SELECT语句的句法和使用;

SQL的数据更新:插入、删除和修改语句;视图的创建和撤消,对视图更新操作的限制;嵌入式SQL:预处理方式,使用规定,使用技术,动态SQL语句。

§0前导知识

关系模型及其基本术语:用二维表格表示实体集,外键表示实体间联系的模型称为关系模型;关系:对应二维表格;元组:表中的行;属性:表中的列;

§0前导知识

关键码超键:能唯一标识元组的属性组合(可能存在多余的属性)。候选键:能唯一标识元组的最小属性组合。主键:若一个关系中有多个候选键,则选其中的一个为关系的主键。外键:若一个关系R中包含有另一个关系S的主键所对应的属性组F,则称F为R的外键。称关系S为参照关系,R为依赖关系。

§0前导知识

关系数据库的三级结构存储文件1存储文件2存储文件3存储文件4用户1用户2用户3用户4视图1视图2基本表1基本表2基本表3基本表4外模式模式内模式

§1SQL概貌及特点一、SQL数据库的体系结构

SQL数据库的体系结构基本上是三级模式结构。

在SQL中:外模式对应于视图,模式对应于基本表,元组称为“行”,属性称为“列”,内模式对应于存储文件。

二、SQL的组成

SQL主要分成四个部分:数据定义;数据操纵;数据控制;嵌入式SQL的使用。

三、SQL的主要特点

1、一体化;

2、两种使用方式,统一的语法结构;

3、高度非过程化;

4、语言简洁,易学易用。§2SQL的数据定义模式的定义(数据库)基本表的定义

索引的定义(自学)视图的定义§2SQL的数据定义一、SQL模式的创建和撤消:1、SQL模式的创建

CREATESCHEMA<模式名>AUTHORIZATION<用户名>2、SQL模式的撤消

DROPSCHEMA<模式名>[CASCADE|RESTRICT]CREATEDATABASE<数据库名>DROPDATABASE<数据库名>

例:创建工程数据库PROJECT

CREATEDATABASEPROJECT

例:撤消工程数据库PROJECTDROPDATABASEPROJECT

二、基本表的创建、修改和撤消

1、基本表的创建

CREATETABLESQL模式名.基本表名(列名类型,

……

完整性约束,

……)

完整性规则主要有三种:

主键子句(PRIMARYKEY);

检查子句(CHECK);

外键子句(FOREIGNKEY)。SQL提供的基本数据类型:数值型:INTEGER长整数(也可写成INT)

SMALLINT短整数

REAL取决于机器精度的浮点数

DOUBLEPRECISION取决于机器精度的双精度浮点数:FLOAT(n)浮点数,精度至少为n位数字;NUMERIC(p,d)定点数,由p位数字(不包括符号、小数点)组成,小数点后面有d位数字;

也可写成:DECIMAL(P,d)或DEC(P,d))SQL提供的基本数据类型

字符串型:CHAR(n)长度为n的定长字符串

VARCHAR(n)具有最大长度为n的变长字符串位串型:BIT(n)长度为n的二进制位串

BITVARYING(n)最大长度为n的变长二进制位时间型:DATE日期,包含年、月、日,YYYY—MM-DDTIME时间,包含时、分、秒,HH:MM:SS【例4.1】在有关工程项目的数据库中,有四个关系,其结构如下:供应商关系:S(SNO,SNAME,SADDR)零件关系:P(PNO,PNAME,COLOR,WEIGHT)工程项目关系:J(JNO,JNAME,JCITY,BALANCE)供应情况关系:SPJ(SNO,PNO,JNO,PRICE,QTY)例:工程项目数据库PROJECT中有四个关系,其结构如下:供应商关系:

S(SNO,SNAME,SADDR)零件关系:

P(PNO,PNAME,COLOR,WEIGHT)工程项目关系:J(JNO,JNAME,JCITY,BALANCE)供应情况关系:SPJ(SNO,PNO,JNO,PRICE,QTY)可用下列语句创建表S:CREATETABLES(SNOCHAR(4)NOTNULL,SNAMECHAR(20)NOTNULL,SADDRCHAR(20),

PRIMARYKEY(SNO));可用下列语句创建表P:

CREATETABLEP(PNOCHAR(4)NOTNULL,PNAMECHAR(20)NOTNULL,COLORCHAR(8),WEIGHTSMALLINT,PRIMARYKEY(PNO));可用下列语句创建表J:

CREATETABLEJ(JNOCHAR(4)NOTNULL,JNAMECHAR(20),JCITYCHAR(20),BALANCENUMERIC(7,2),PRIMARYKEY(JNO));可用下列语句创建表SPJ:CREATETABLESPJ(SNOCHAR(4)NOTNULL,PNOCHAR(4)NOTNULL,JNOCHAR(4)NOTNULL,PRICENUMERIC(7,2),QTYSMALLINT,PRIMARYKEY(SNO,PNO,JNO),FOREIGNKEY(SNO)REFERENCESS(SNO),FOREIGNKEY(PNO)REFERENCESP(PNO),FOREIGNKEY(JNO)REFERENCESJ(JNO),CHECK(QTYBETWEEN0AND10000));【例4.1】在有关工程项目的数据库中,有四个关系,其结构如下:供应商关系:S(SNO,SNAME,SADDR)零件关系:P(PNO,PNAME,COLOR,WEIGHT)工程项目关系:J(JNO,JNAME,JCITY,BALANCE)供应情况关系:SPJ(SNO,PNO,JNO,PRICE,QTY)例:学生数据库STUDENT中有三个关系,其结构如下:学生关系:

S(SNO,SNAME,AGE,SEX,SDEPT)

课程关系:

C(CNO,CNAME,CDEPT,TNAME)

学习关系:SC(SNO,CNO,GRADE)可用下列语句创建表S:CREATETABLES(SNOCHAR(4)NOTNULL,SNAMECHAR(20)NOTNULL,AGECHAR(20),SEXCHAR(2),SDEPTCHAR(10),

PRIMARYKEY(SNO));可用下列语句创建表C:CREATETABLEC(CNOCHAR(4)NOTNULL,CNAMECHAR(20)NOTNULL,CDEPTCHAR(10),TNAMECHAR(8),PRIMARYKEY(CNO));可用下列语句创建表SC:CREATETABLESC(SNOCHAR(4)NOTNULL,CNOCHAR(4)NOTNULL,GRADENUMERIC(7,2),

PRIMARYKEY(SNO,CNO),

FOREIGNKEY(SNO)REFERENCESS(SNO),FOREIGNKEY(CNO)REFERENCESP(CNO),CHECK(GRADEBETWEEN0AND100));主键子句外键子句检查子句2.基本表结构的修改增加新的属性:删除原有的属性:ALTERTABLE基本表名ADD新属性名新属性类型例:在基本表S中增加一个电话号码(TELE)属性语句如下:

ALTERTABLESADDTELECHAR(12);ALTERTABLE基本表名DROP属性名[CASCADE|RESTRICT]例:在表S中删除电话号码(TELE)属性,并且将引用该属性的所有视图和约束也一起删除,可用下列语句:

ALTERTABLESDROPTELECASCADE;

§3SQL的数据查询

SQL的数据查询(SELECT语句)是SQL的核心内容。1.SELECT语句的来历在关系代数中最常用的式子是下列表达式:

πA1,…,An(σF(R1×…×Rm))

这里R1、…、Rm为关系,F是公式,A1、…、An为属性。为此SQL设计成SELECT–FROM-WHERE句型:

SELECTA1,…,An

FROMR1,…,Rm

WHEREF2.SELECT语句格式:

SELECT[DISTINCT]目标表的列名或列表达式序列

FROM

基本表名(或)视图名序列|表引用

[WHERE

行条件表达式]

[GROUP

BY

列名1序列[HAVING

组条件表达式]]

[ORDER

BY

列名2[ASC|DESC]序列];

整个语句的执行过程如下:

2、选取满足WHERE子句中给出的条件表达式的元组。3、按GROUP子句中指定列的值分组,同时提取满足HAVING子句中组条件表达式的那些组。4、按SELECT子句中给出的列名或列表达式求值输出。5、ORDER子句对输出的目标表进行排序,按附加说明ASC升序排列,或按DESC降序排列。1、读取FROM子句中基本表、视图的数据,执行笛卡尔积操作。SELECT语句中:

WHERE子句称为“行条件子句”,

GROUP子句称为“分组子句”,

HAVING子句称为“组条件子句”,

ORDER子句称为“排序子句”。

在WHERE子句的行条件表达式中可使用下列运算符:

算术比较运算符:<,<=,>,>=,=,<>或!=;逻辑运算符:AND,OR,NOT;集合成员资格运算符:IN,NOTIN;谓词:EXISTS,ALL,SOME,UNIQUE;聚合函数:AVG,MIN,MAX,SUM,COUNT;集合运算符:UNION,INTERSECT,EXCEPT。

3.举例

单表查询查询仅涉及一个表,是一种最简单的查询操作选择表中的若干列选择表中的若干元组对查询结果排序使用集函数对查询结果分组

1、查询全体学生的姓名、学号、所在系。2、查询全体学生的详细记录。3、查全体学生的姓名及其出生年份。别名的使用4、查询选修了课程的学生学号。5、查询计算机系全体学生的名单。6、查询考试成绩有不及格的学生的学号。7、查询年龄在20~23岁(包括20岁和23岁)之间的学生的姓名、系别和年龄。8、查询年龄不在20~23岁之间的学生姓名、系别和年龄9、查询信息系(IS)、数学系(MA)和计算机科学系(CS)学生的姓名和性别。10、查询所有姓刘学生的姓名、学号和性别。通配符%(百分号)

代表任意长度(长度可以为0)的字符串。例:a%b表示以a开头,以b结尾的任意长度的字符串。如acb,addgb,ab等都满足该匹配串。_(下横线)

代表任意单个字符。例:a_b表示以a开头,以b结尾的长度为3的任意字符串。如acb,afb等都满足该匹配串。11、查询姓"欧阳"且全名为三个汉字的学生的姓名12、某些学生选修课程后没有参加考试,所以有选课记录,但没有考试成绩。查询缺少成绩的学生的学号和相应的课程号。13、查询选修了3号课程的学生的学号及其成绩,查询结果按分数降序排列。

联接操作(多表查询)

联接条件可在WHERE中指定,也可以在FROM子句中指定。

在FROM子句中指定联接条件时,SQL2将联接操作符分成:

联接类型、联接条件。联接类型:决定了如何处理联接条件中不匹配的元组。联接条件:决定了两个关系中哪些元组应该匹配。联接类型中的OUTER字样可不写。联接类型联接类型说明INNERJOIN内联接:LEFTOUTERJOIN左外联接:RIGHTOUTERJOIN右外联接:FULLOUTERJOIN完全外联接:CROSSJOIN交叉联接:结果为两个联接表中匹配行的联接。

结果包括“左”表(出现在JOIN子句的最左边)中的所有行。不包括右表中的不匹配行。

结果包括“右”表(出现在JOIN子句的最右边)中的所有行。不包括左表中的不匹配行。结果包括所有联接表中的所有行,不论它们是否匹配

结果包括两个联接表中所有可能的行组合。交叉联接返回的是两个表的笛卡儿积ABCabcbbfcadBCDbcdbceadbefgABCDabcdabcecadbbbfnullnullefg关系R关系SABCDabcdabcecadbbbfnullABCDabcdabcecadbnullefg联接条件联接条件说明ON联接条件具体列出两个关系在哪些相应属性上做联接条件比较。联接条件应写在联接类型的右边。也可以在WHERE子句中指定,一般为内联接例1:查询选修2号课程的学生姓名。SELECTSNAMEFROMS,SCWHERES.SNO=SC.SNOANDCNO=‘2’

SELECTSNAMEFROMSCINNERJOINSONS.SNO=SC.SNOWHERECNO=‘2’2、检索选修了C1和C3的课程的学生的学号。3、查询每一门课的间接先修课(即先修课的先修课)。SELECTX.Cno,Y.CpnoFROMCX,CYWHEREX.Cpno=Y.Cno;SELECTDISTINCTX.SNOFROMSCXINNERJOINSCYONX.SNO=Y.SNOWHERE(X.CNO=‘C1’)AND(Y.CNO=‘C3’);

嵌套操作例:查询选修2号课程的学生姓名。SELECTSNAMEFROMSWHERESNOIN(SELECTSNOFROMSCWHERECNO=‘2’); 嵌套查询分类不相关子查询:子查询的查询条件不依赖于父查询相关子查询:子查询的查询条件依赖于父查询SELECTSNAMEFROMSWHEREEXISTS(SELECT*FROMSCWHERESNO=S.SNOANDCNO=‘2’); SELECTSNAMEFROMSWHERE‘2’IN(SELECTSNOFROMSCWHERESNO=S.SNO); 带有IN谓词的子查询1、查询与“刘晨”在同一个系学习的学生。SELECTSno,Sname,SdeptFROMSWHERESdeptIN(SELECTSdeptFROMSWHERESname=‘

刘晨’);2、查询没有选修1号课程的学生姓名。3、查询选修了课程名为“信息系统”的学生学号和姓名SELECTSno,SnameFROMSWHERESnoIN(SELECTSnoFROMSCWHERECnoIN(SELECTCnoFROMCWHERECname=‘信息系统’));SELECTSnameFROMSWHERESNONOTIN(SELECTSNOFROMSCWHERECNO=‘1’)带有比较运算符的子查询

使用范围当能确切知道内层查询返回单值时,可用比较运算符(>,<,=,>=,<=,!=或<>)。与ANY或ALL谓词配合使用查询与“刘晨”在同一个系学习的学生。

SELECTSno,Sname,SdeptFROMStudentWHERESdept=(SELECTSdeptFROMStudentWHERESname='刘晨‘);注意:子查询一定要跟在比较符之后带有ANY或ALL谓词的子查询谓词语义ANY:任意一个值 ALL:所有值需要配合使用比较运算符>ANY 大于子查询结果中的某个值

>ALL 大于子查询结果中的所有值<ANY 小于子查询结果中的某个值<ALL 小于子查询结果中的所有值>=ANY 大于等于子查询结果中的某个值>=ALL 大于等于子查询结果中的所有值<=ANY 小于等于子查询结果中的某个值<=ALL 小于等于子查询结果中的所有值=ANY 等于子查询结果中的某个值=ALL 等于子查询结果中的所有值(通常没有实际意义)!=(或<>)ANY 不等于子查询结果中的某个值!=(或<>)ALL 不等于子查询结果中的任何一个值例:查询其他系中比信息系某一学生年龄小的学生姓名和年龄

SELECTSname,SageFROMSWHERESage<ANY(SELECTSageFROMSWHERESdept='IS')

ANDSdept<>'IS';/*注意这是父查询块中的条件*/SELECTSname,SageFROMSWHERESDEPT!=‘IS’ANDSage<(SELECTMAX(SAGE) FROMS WHERESDEPT=‘IS’)ANY和ALL谓词有时可以用集函数实现用集函数实现子查询通常比直接用ANY或ALL查询效率要高,因为前者通常能够减少比较次数ANY与ALL与集函数的对应关系

=

<>或!=<<=>>=ANY

IN

--

<MAX<=MAX>MIN>=MINALL--

NOTIN

<MIN<=MIN>MAX>=MAX例:查询其他系中比信息系所有学生年龄都小的学生姓名及年龄。

方法二:用集函数

SELECTSname,Sage

FROMSWHERESage<(SELECTMIN(Sage)FROMSWHERESdept=‘IS‘)ANDSdept<>’IS‘;方法一:用ALL谓词SELECTSname,SageFROMStudentWHERESage<ALL(SELECTSageFROMSWHERESdept=‘IS‘)ANDSdept<>’IS’;带有EXISTS谓词的子查询EXISTS谓词NOTEXISTS谓词用EXISTS/NOTEXISTS实现全称量词用EXISTS/NOTEXISTS实现逻辑蕴函1.EXISTS谓词存在量词

带有EXISTS谓词的子查询不返回任何数据,只产生逻辑真值“true”或逻辑假值“false”。若内层查询结果非空,则返回真值若内层查询结果为空,则返回假值由EXISTS引出的子查询,其目标列表达式通常都用*,因为带EXISTS的子查询只返回真值或假值,给出列名无实际意义2.NOTEXISTS谓词例:查询所有选修了1号课程的学生姓名。

SELECTSnameFROMSWHEREEXISTS(SELECT*FROMSCWHERESno=S.SnoANDCno=‘1’);例:查询没有选修1号课程的学生姓名。SELECTSnameFROMSWHERENOTEXISTS(SELECT*FROMSC WHERESno=S.SnoANDCno=‘1’);例:和刘晨在同一个系的学生学号、姓名。

SELECTSno,SnameFROMSXWHEREEXISTS

(SELECT*FROMSWHERESdept=X.SdeptANDSname=‘刘晨’);用EXISTS/NOTEXISTS实现全称量词(难点)SQL语言中没有全称量词(Forall)可以把带有全称量词的谓词转换为等价的带有存在量词的谓词:

(x)P≡(x(P))例:查询选修了全部课程的学生姓名。SELECTSnameFROMSWHERENOTEXISTS

(SELECT*FROMCWHERENOTEXISTS(SELECT*FROMSCWHERESno=S.SnoANDCno=C.Cno));

用EXISTS/NOTEXISTS实现逻辑蕴函(难点)SQL语言中没有蕴函(Implication)逻辑运算可以利用谓词演算将逻辑蕴函谓词等价转换为:

pq≡p∨q例:查询至少选修了学生95002选修的全部课程的学生号码。解题思路:用逻辑蕴函表达:查询学号为x的学生,对所有的课程y,只要95002学生选修了课程y,则x也选修了y。形式化表示: 用P表示谓词“学生95002选修了课程y”

用q表示谓词“学生x选修了课程y”

则上述查询为:(y)pq等价变换:

(y)pq≡(y((pq))≡(y((p∨q)≡

y(p∧q)变换后语义:不存在这样的课程y,学生95002选修了y,而学生x没有选。

SELECTDISTINCTSnoFROMSCXWHERENOTEXISTS(SELECT*FROMSCYWHEREY.Sno='95002'ANDNOTEXISTS(SELECT*FROMSCZWHEREZ.Sno=X.SnoANDZ.Cno=Y.Cno));聚合函数SQL提供了下列聚合函数:COUNT(*)计算元组的个数COUNT(列名)对一列中的值计算个数SUM(列名)求某一列值的总和(此列的值必须是数值)AVG(列名)求某一列值的平均值(此列的值必须是数值)MAX(列名)求某一列值的最大值MIN(列名)求某一列值的最小值DISTINCT1、查询学生总人数。2、查询选修了课程的学生人数。3、计算1号课程的学生平均成绩。4、求各个课程号及相应的选课人数。SELECT语句的语义有三种情况(SQL标准):

第一种情况:SELECT语句中未使用分组子句,也未使用聚合操作,那么SELECT子句的语义是对查询的结果执行投影操作。如:

SELECTSNO,SNAME FROMS WHERESEX='男';第二种情况:SELECT语句中未使用分组子句,但在SELECT子句中使用了聚合操作,此时SELECT子句的语义是对查询结果执行聚合操作。如: SELECTCOUNT(*)count_男,AVG(AGE)avg_ageFROMSWHERESEX='男';

该语句是求男同学的人数和平均年龄。第三种情况:SELECT语句使用了分组子句和聚合操作,此时SELECT子句的语义是对查询结果的每一分组去做聚合操作。如:SELECTcno,count(*)FROMSC GROUPBYcno;

该语句是求每门课的选课人数。

注意:

通常SELECT语句中使用了分组子句就会有聚合操作。但执行聚合操作不一定要用分组子句。

如:求男同学的人数,此时聚合值只有一个,因此不必分组。

但同一个聚合操作的值有多个时,必须使用分组子句。

如:求每一年龄的学生人数。此时聚合值有多个,与年龄有关,因此必须分组。1、查询学生总人数。2、查询选修了课程的学生人数。3、计算1号课程的学生平均成绩。4、求各个课程号及相应的选课人数。5、求各个课程号及相应的课程成绩在90分以上的学生人数。6、查询选修了3门以上课程的学生学号及选修门数,查询结果按门数降序排列,若门数相同,按学号升序排列:加姓名7、查询有3门以上课程在90分以上的学生的学号及90分以上的课程数。8、查询所有成绩在80分以上的学生学号。9、查询有成绩在90分以上的学生学号。§4SQL的数据更新

SQL的数据更新包括:数据插入、修改数据和数据删除等操作。

一、数据插入

1.插入单个元组:

INSERTINTO

基本表名(列名表)

VALUES

(元组值)

例:

INSERTINTOSC(SNO,CNO)VALUES('S3','C3')INSERTINTOSCVALUES(‘S3’,‘C3’,90)

2.插入子查询的结果:

INSERTINTO

基本表名(列名表)

SELECT

查询语句;例如:

CREATETABLES_AVG_GRADE(SNOCHAR(4),AVGGRADENUMERIC(7,2));INSERTINTOS_AVG_GRADESELECTSNO,AVG(GRADE)FROMSCGROUPBYSNO;

二、数据删除删除关系中满足条件的元组语句的句法如下:

DELETEFROM<表名>

WHERE<条件表达式>举例:把课程名为”数据库原理”的成绩从表SC中删除.

DELETEFROMSCWHERECNOIN(SELECTCNOFROMCWHERECNAME='数据库原理');

三、数据修改

UPDATE基本表名

SET列名=值表达式[,列名=值表达式…][WHERE条件表达式]举例:把课程名为”数据库原理”的成绩提高10%.

UPDATESCSETGRADE=1.1*GRADEWHERECNOIN(SELECTCNOFROMCWHERECNAME='数据库原理');把课程名为”数据库原理”的学分增加1分,老师改为王。

UPDATECSETCREDIT=CREDIT+1,TNAME=‘WANG’WHERECNAME='数据库原理';

§5

视图操作

在SQL中,外模式一级数据结构的基本单位是视图(View)。视图是从若干基本表和(或)其他视图构造出来的表。在创建一个视图时,系统把视图的定义存放在数据字典中,而不存储视图对应的数据,在用户使用视图时才去求对应的数据。

视图被称为“虚表”。一、

视图的创建

CREATEVIEW<视图名>(列名表)

AS<SELECT查询语句>例:在教学数据库中基本表SC上,建立一个学生学习情况视图:

CREATEVIEWS_GRADE(SNO,C_NUM,AVG_GRADE) AS(SELECTSNO,COUNT(CNO),AVG(GRADE) FROMSC GROUPBYSNO);二、视图的撤消

DROPVIEW视图名例:撤消S_GRADE视图,可用下列语句实现:

DROPVIEWS_GRADE;三、视图的查询系统在实现对视图的查询时,根据数据字典的定义将对视图的查询转换为对基本表的查询。例:对学生学习情况视图执行如下操作:① SELECT*FROMS_GRADE;

相应的查询转换操作如下:

SELECTSNO,COUNT(CNO)ASC_NUM,AVG(GRADE)ASAVG_GRADEFROMSCGROUPBYSNO;② SELECTSNO,C_NUM FROMS_GRADE

WHEREAVG_GRADE>80;

相应的查询转换操作如下:SELECTSNO,COUNT(CNO)ASC_NUMFROMSCGROUPBYSNO

HAVINGAVG(GRADE)>80;③ SELECTSNO,AVG_GRADE FROMS_GRADE

WHEREC_NUM>(SELECTC_NUMFROMS_GRADE

WHERESNO=‘S4’);

相应的查询转换操作如下:SELECTSNO,AVG(GRADE)ASAVG_GRADEFROMSCGROUPBYSNO

HAVINGCOUNT(CNO)>(SELECTCOUNT(CNO)FROMSC

WHERESNO=‘S4’GROUPBYSNO);

四、视图的更新操作对于视图的更新操作(INSERT、DELETE、UPDATE)有以下三条规则:①如果一个视图是从多个基本表使用联接操作导出的,那么不允许对这个视图执行更新操作。②如果在导出视图的过程中,使用了分组和聚合操作,也不允许对这个视图执行更新操作。③如果视图是从单个基本表使用选择、投影操作导出的,并且包含了基本表的主键或某个候选键,那么这样的视图称为“行列子集视图”,并且可以被执行更新操作。在SQL2中,允许更新的视图在定义时,必须加上“WITHCHECKOPTION”短语。例:如果定义“计算机应用”学生视图:

CREATEVIEWSTUDENT_COMPUTER(SNO,SNAME,SEX,AGE)ASSELECTSNO,SNAME,SEX,AGEFROMSWHERESDEPT=‘计算机应用’

该视图是从单个关系仅使用了选择和投影导出的,而且包括键SNO,因此是可以修改的。如执行插入操作:

INSERTINTOSTUDENT_COMPUTERVALUES(‘S99’,‘王敏’,‘男’,22);系统自动会把它转换变成下列语句:

INSERTINTOSVALUES(’S99’,‘王敏’,‘男’,22,‘计算机应用’

);

对于学生学习情况视图:

CREATEVIEWS_GRADE(SNO,C_NUM,AVG_GRADE) ASSELECTSNO,COUNT(CNO),AVG(GRADE)

FROMSC

GROUPBYSNO执行:UPDATES_GRADE SETSNO='S3' WHERESNO='S4';

不允许。C_NUM是对SC中的学生选修门数进行统计,在未更改SC表时,要在视图S_GRADE中更改门数,是不可能的。执行:DELETEFROMS_GRADEWHEREC_NUM>4;

也不允许的。在视图S_GRADE中删除选修门数在4门以上的学生元组,势必造成SC中这些学生学习元组的删除,这不一定是用户的原意,因此使用分组和聚合操作的视图,不允许用户执行更新操作。

嵌入式SQL

SQL语言有两种使用方式:一种是在终端交互方式下使用,称为交互式SQL;另一种是嵌入在高级语言的程序中使用,称为嵌入式

SQL,而这些高级语言可以是C、PASCAL、COBOL或

PL/I等称为宿主语言。§5嵌入式SQL的使用技术使用差别:SQL是基于关系数据模型的语言;

高级语言是基于基本数据类型(整型、字符串型、记录、数组等)的语言。譬如,SQL语句不能直接使用指针、数组等数据结构;

高级语言一般不能直接进行集合的操作。为了能在宿主语言的程序中嵌入SQL语句,必须作某些规定。嵌入式SQL的实现,有两种处理方式:1、扩充宿主语言的编译程序,使之能处理SQL语句;2、采用预处理方式。目前多数系统采用后一种方式。

预处理方式是:

先由预处理程序对源程序进行扫描,识别出SQL语句,并处理成宿主语言的函数调用形式;然后再用宿主语言的编译程序把源程序编译成目标程序。通常DBMS制造商提供一个SQL函数定义库,供编译时使用。源程序的预处理和编译的具体过程如下图所示:目标程序宿主语言十嵌入式SQL

预处理程序

宿主语言十函数调用宿主语言编译程序一、嵌入式SQL使用时必须解决的问题①为区分SQL语句与宿主语言语句,在所有的SQL语句前必须加上前缀标识“EXECSQL”,并以“ENDEXEC”作为语句结束标志。格式:EXECSQL

<SQL语句>END_EXEC结束标志在不同的宿主语言中是不同的,在C和PASCAL语言程序中规定结束标志不用END_EXEC,而使用分号“;”。②数据库工作单元和主程序工作单元之间的通讯允许嵌入的SQL语句引用宿主语言的程序变量(称为共享变量)。并规定:

在引用这些变量时必须在这些变量前加冒号“:”作为前缀标识,以示与数据库中变量有区别;这些变量由宿主语言的程序定义;

由SQL的BEGINDECLARESECTION与ENDDECLARESECTION语句之间说明。

而主语言不能引用数据库中的字段变量。SQL2规定,SQLSTATE是一个特殊的共享变量,

起着解释SQL语句执行状况的作用,是一个由5个字符组成的字符数组。SQLSTATE=0:表示SQL语句执行成功;SQLSTATE<>0:表示执行SQL语句时发生的各种特殊情况。譬如“02000”用来表示未找到元组。在执行一个SQL语句后,程序可以根据SQLSTATE的值转向不同的分支,以控制程序的流向。③引入游标机制:

将集合操作转换为单元组处理。

SQL的执行是面向集合的,一条SQL语句原则上可以产生或处理多条记录。宿主语言是面向记录的,一组主变量一次只能存放一条记录。为此引入游标来协调SQL语言与主语言的不同数据处理方式。二、与游标有关的语句:①定义游标语句(DECLARE)游标是与某一查询结果相联系的符号名。

EXECSQLDECLARE

<游标名>

CURSORFOR

<SELECT语句>[FORUPDATE[OF<字段名1><,…,字段名n>]];

END_EXEC

这是一个说明语句,定义中的SELECT语句并不立即执行。EXECSQLDECLARE

scx

CURSORFOR

SELECTSNO,CNO,GRADEFROMSCWHERESNO=(SELECTSNOFROMSWHERESNAME=:givensname)

FORUPDATEOFGRADE;②打开游标语句(OPEN)打开游标语句使游标处于活动状态。与游标相应的查询语句被执行。游标指向查询结果的第一个记录之前。句法如下:

EXECSQLOPEN<游标名>END_EXEC

③游标推进语句(FETCH)此时游标推进一个记录,并把游标指向的记录(称为当前行)中的值取出,送到INTO子句后相应的主变量中。句法如下:

EXECSQLFETCHFROM

<游标名>

INTO<变量表>

END_EXECFETCH语句常用于宿主语言程序的循环结构中,并借助宿主语言的处理语句逐一处理查询结果中的一个个元组。在游标处于活动状态时,可以修改和删除游标指向的元组。④

关闭游标语句(CLOSE)关闭游标,使它不再和查询结果相联系。关闭了的游标,可以再次打开,与新的查询结果相联系。句法如下:

EXECSQLCLOSE<游标名>END_EXEC三、嵌入式SQL的使用技术⑴在嵌入式SQL中,SQL的数据定义DDL与控制语句DCL都不需要使用游标。它们是嵌入式SQL中最简单的一类语句,不需要返回结果数据,也不需要使用主变量。在主语言中嵌入SQL说明性语句(DECLARE)及控制语句(GRANT),只要给语句加上前缀EXECSQL和语句结束符END_EXEC即可。在C语言中,用分号;代替END_EXEC例:在C语言中说明共享变量:EXECSQLBEGINDECLARESECTIONintgrade,raise;chargivencno[5],cname[13],tname[9];

chargivensno[5],sname[9],sdept[11];

charSQLSTATE[6];EXECSQLENDDECLARESECTION;

⑵不涉及游标的嵌入式SQLDML语句

a.对于INSERT、DELETE和UPDATE语句,只要加上前缀标识“EXECSQL”和结束标志“END_EXEC”,就能嵌入在宿主语言程序中使用。例:①在关系C中插入一门新的课程,各属性值已在相应的共享变量中:

EXECSQLINSERTINTOC(CNO,CNAME,TNAME)

VALUES(:givencno,:cname,:tname);②从关系SC中删除一个学生的所有选课,该学生的姓名由共享变量sname提供。

EXECSQLDELETEFROMSCWHERESNO=(SELECTSNOFROMSWHERESNAME=:sname);③把“数据库”课程的全部成绩增加某个值(该值由共享变量raise提供)。

EXECSQLUPDATESCSETGRADE=GRADE+:raiseWHERECNOIN(SELECTCNOFROMCWHERECNAME=‘数据库’);b.对于SELECT语句,如果已知查询结果肯定是单元组时,可直接嵌入在主程序中使用,此时在SELECI语句中增加一个INTO子句,指出找到的值应送到相应的共享变量中去。例:在关系S中根据共享变量givensno的值检索学生的姓名和所在系。

例:在关系S中根据共享变量givensno的值检索该学生的姓名和所在系:

EXECSQLSELECTSNAME,SDEPTINTO:sname,:sdeptFROMSWHERESNO=:givensno;此处sname,sdept,givensno都是共享变量,已在主程序中定义,并用SQL的DECLARE语句加以说明,在引用是加上“:”作为前缀标识,以示与数据库中变量区别。

⑶涉及游标的嵌入式SQLDML语句

a、当SELECT语句查询结果是多个元组时,此时要用游标机制把多个元组一次一个地传送给宿主语言程序处理。例:在关系SC表中检索某学生(学生名由共享变量givensname给出)选课信息(SNO,CNO,GRADE),

该查询的C语言程序段:

EXECSQLBEGINDECLARESECTION;intgrade,rise;charsno[5],cno[5],givensname[9],SQLSTATE[6];EXECSQLENDDECLARESECTION;EXECSQLDECLAREscxCURSORFORSELECTSNO,CNO,GRADEFROMSCWHERESNO=(SELECTSNOFROMSWHERESNAME=:givensname)

FORUPDATEOFGRADE;EXECSQLOPENscx;

while(1){EXECSQLFETCHFROMscxINTO:sno,:cno,:grade;if(SQLCA.SQLSTATE=='02000’)

/﹡已取完查询结果中的所有元组﹡/break;if(SQLCA.SQLSTATE!=’0’)/﹡取数据出错﹡/break;

…/﹡对游标所取的数据进行处理﹡/printf(“%s,%s,%d”,sno,cno,grade);

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论