关系数据库标准语言SQL 第3章 SQL概述 数据定义 查询 更新 视图 数据控制 嵌入式SQL 2019/12/6 数据库原理
1974年,由Boyce和Chamberlin提出。 1975-1979,IBM公司San Jose Research Lab研制了 ● SQL的发展及现状 1974年,由Boyce和Chamberlin提出。 1975-1979,IBM公司San Jose Research Lab研制了 关系数据库管理系统原型System R并实现了这种语言。 1986年美国国家标准局(ANSI)的数据库委员会X3H2批准 SQL作为关系数据库语言的美国标准(SQL-86) 。 ANSI 不断修改和完善SQL标准,公布了SQL-89、 SQL-92(SQL2)、SQL-99(SQL3) 大部分DBMS产品都支持SQL,成为操作数据库的标准语言 2019/12/6 数据库原理
3.1 SQL概述 3.1.1 SQL的特点 综合统一 以同一种语法结构提供两种使用方式 集DDL、DML、DCL的功能于一体,可以独立完成数据库生命周期中的全部活动。 高度非过程化 无需了解存取路径,存取路径的选择以及SQL语句的操作过程由系统自动完成。 面向集合的操作方式 操作对象、查找结果、插入、删除、更新操作的对象可以是元组集合。 以同一种语法结构提供两种使用方式 可独立的用于联机交互的使用方式,用户可在终端键入SQL命令对数据库进行操作;SQL语句可嵌入到高级语言程序中,供程序员设计程序时使用。 语言简单,易学易用 核心功能只有9个动词。 2019/12/6 数据库原理
数据查询 (Data Query) S 数据操纵 Q (Data Manipulation) L语言 数据定义 SQL 功能 数据查询 数据定义 数据操纵 数据控制 动 词 SELECT CREATE, DROP, ALTER INSERT, UPDATE, DELETE GRANT, REVOKE 表3.1 SQL语言的动词 数据定义 (Data Definition) 数据控制 (Data Control) 2019/12/6 数据库原理
3.1.2 SQL语言的基本概念 SQL 用 户 视图1 视图2 外模式 基本表1 基本表2 基本表3 基本表4 模 式 存储文件1 存储文件2 内模式 图3.1 SQL对关系数据库模型的支持 2019/12/6 数据库原理
基本概念: 用户可以用SQL语言对视图(View)和基本表(Base Table)进行查询等操作,在用户观点里,视图和表一样,都是关系。 视图是从一个或多个基本表中导出的表,本身不存储在数据库中,只有其定义,可以将其理解为一个虚表。 基本表是本身独立存在的表,每个基本表对应一个存储文件,一个表可以带若干索引,存储文件及索引组成了关系数据库的内模式。 2019/12/6 数据库原理
3.2 数据定义 操作对象 表 视 图 索 引 操作方式 创 建 CREATE TABLE 删 除 DROP TABLE 修 改 ALTER TABLE CREATE INDEX DROP INDEX CREATE VIEW DROP VIEW 表3.2 SQL的数据定义语句 视图是基于基本表的虚表,索引是依附于基本表的,因此,SQL通常不提供修改视图定义和索引定义的操作。(删除后重建;Oracle允许直接修改视图定义) 2019/12/6 数据库原理
3.2.1 定义、删除与修改基本表 定义基本表 格式:CREATE TABLE <表名> (<列名> <数据类型>[列级完整性约束条件] [,<列名> <数据类型>[列级完整性约束条件]]…… [,<表级完整性约束条件>]); 建立一个新表,表中无记录 2019/12/6 数据库原理
( Sno CHAR(5) NOT NULL UNIQUE, /* 列级完整性 约束条件 Sname CHAR(20) UNIQUE, 例1 :建立学生表Student,它由学号Sno、姓名Sname、性别Ssex、年龄Sage、所在系Sdept五个属性构成。其中学号不能为空,值是唯一的,并且姓名取值也唯一。 CREATE TABLE Student ( Sno CHAR(5) NOT NULL UNIQUE, /* 列级完整性 约束条件 Sname CHAR(20) UNIQUE, Ssex CHAR(1), Sage INT, Sdept CHAR(15)); 2019/12/6 数据库原理
( S# CHAR(6) NOT NULL, /* 学号 SNAME CHAR(8) NOT NULL, /* 姓名 例2 :建立学生S、课程C、选课SC三个表 S表: CREATE TABLE S ( S# CHAR(6) NOT NULL, /* 学号 SNAME CHAR(8) NOT NULL, /* 姓名 SAGE SMALLINT, /* 年龄 SD CHAR(10), /* 系名 SEX CHAR(2) DEFAULT '男' /* 性别 CHECK((SEX='男') OR (SEX='女')), PRIMARY KEY (S#)); 2019/12/6 数据库原理
(C# CHAR(6) NOT NULL, /* 课程号 CNAME CHAR(30) NOT NULL, /* 课程名 例2 :建立学生S、课程C、选课SC三个表 C表: CREATE TABLE C (C# CHAR(6) NOT NULL, /* 课程号 CNAME CHAR(30) NOT NULL, /* 课程名 TNAME CHAR(8), /* 教师姓名 PC# CHAR(6), /* 先行课 PRIMARY KEY (C#)); 2019/12/6 数据库原理
(S# CHAR(6) NOT NULL, /* 学号 C# CHAR(6) NOT NULL, /* 课程号 例2 :建立学生S、课程C、选课SC三个表 SC表: CREATE TABLE SC (S# CHAR(6) NOT NULL, /* 学号 C# CHAR(6) NOT NULL, /* 课程号 GR SMALLINT DEFAULT NULL, /* 成绩 PRIMARY KEY (S#,C#), FOREIGN KEY (S#) REFERENCES S(S#), FOREIGN KEY (C#) REFERENCES C(C#), CHECK (GR IS NULL) OR (GR BETWEEN O AND 100)) ; 2019/12/6 数据库原理
修改基本表 基本表的修改操作: 改变表名 增加列 改变列的数据类型 删除列的约束 删除列 改变列名 2019/12/6 数据库原理
格式:ALTER TABLE <表名> [ADD <新列名> <数据类型>[完整性约束]] [DROP <完整性约束名>] [MODIFY <列名> <数据类型>] [RENAME <旧表名> TO <新表名>]; 增加新列和新的完整性约束条件 删除指定的完整性约束条件 修改列的定义(列名和数据类型) 改变表名 2019/12/6 数据库原理
例4:在Student表中增加“入学时间”列,数据类型为日期型。 ALETR TABLE Student ADD Scome DATE; 例5:把年龄的数据类型改为半字长整数. ALETR TABLE Student MODIFY Sage SMALLINT; 例6:删除学生姓名必须取唯一值的约束。 ALETR TABLE Student DROP UNIQUE(Sname); 2019/12/6 数据库原理
删除基本表 格式: DROP TABLE <表名>; 删除一个表,及与该表相关的索引、视图、码和外部码。 例7: 删除Student表。 DROP TABLE Student; 2019/12/6 数据库原理
3.2.2 建立与删除索引 建立索引是加快查询速度的有效手段,一个基本表上可建立一个或多个索引,以提供多种存取路径,加快查找速度。 建立与删除索引由DBA或表的属主负责完成,用户不必也不能选择索引。 2019/12/6 数据库原理
建立索引 格式:CREATE [UNIQUE] [CLUSTER] INDEX <索引名> ON <表名> (<列名>[<次序>],[, <列名>[<次序>]]…); 对指定的表的列建立索引。 UNIQUE 表示索引值唯一。 CLUSTER 表示索引是聚簇索引,指索引项的顺序与表中 记录的物理顺序一致。 索引一旦建立,交由系统使用和维护。 2019/12/6 数据库原理
CREATE UNIQUE INDEX SIDX ON S(S#); CREATE UNIQUE INDEX CIDX ON C(C#); 例8: 为学生-课程数据库中的S, C, SC三个表建立索引。其中S表按学号升序建唯一索引,C表按课程号升序建唯一索引,SC表按学号升序和课程号降序建唯一索引。 CREATE UNIQUE INDEX SIDX ON S(S#); CREATE UNIQUE INDEX CIDX ON C(C#); CREATE UNIQUE INDEX SCIDX ON S(S# ASC, C# DESC); 2019/12/6 数据库原理
CREATE CLUSTER INDEX SNAMEIDX ON Student(Sname); 一个基本表最多只能建立一个聚簇索引。建立索引后,更新索引列数据时,往往导致表中记录的物理顺序的变更,代价较大,因此对于经常更新的列不宜建立聚簇索引。 2019/12/6 数据库原理
删除索引 格式: DROP INDEX <索引名>; 例10: 删除Student表的SNAMEIDX索引。 DROP INDEX SNAMEIDX ; 2019/12/6 数据库原理
Select A1, A2, ..., An From R1, R2, ..., Rm Where P 3.3 查 询 数据查询是数据库应用的核心功能。 基本结构 Select A1, A2, ..., An From R1, R2, ..., Rm Where P πA1, A2, ..., An(σp(R1×R2×...×Rm)) From Select Where 2019/12/6 数据库原理
SELECT [ALL|DISTINCT] <目标列表达式> [, <目标列表达式>]…… 格式 SELECT [ALL|DISTINCT] <目标列表达式> [, <目标列表达式>]…… FROM <表名或视图名>[,<表名或视图名>] … [WHERE <条件表达式>] [GROUP BY <列名1> [HAVING <条件表达式>]] [ORDER BY <列名2>[ASC|DESC]]; 2019/12/6 数据库原理
SELECT…FROM常用语句执行过程 SELECT… ⑤ 投影 FROM… ① TABLE→内存 WHERE… ② 选取元组 GROUP… ③ 分组 HAVING… ④ 选择分组 [{UNION|… } ⑥ 查徇结果的集合运算 SELECT… ] ①~⑤ ORDER BY…… ⑦ 排序输出 2019/12/6 数据库原理
3.3.1 单表查询 选择表中的若干列 选择表中的若干元组 对查询结果排序 使用集函数 对查询结果分组 2019/12/6 数据库原理
1.查询指定列 学生表:Student(Sno, Sname, Ssex, Sage, Sdept) 例1. 查询全体学生的学号及姓名。 SELECT Sno, Sname FROM Student; 查询各列的先后顺序可以与表中的顺序不一致。 例2. 查询全体学生的姓名、学号、所在系。 SELECT Sname, Sno, Sdept FROM Student; 2019/12/6 数据库原理
2019/12/6 数据库原理
2.查询全部列 学生表:Student(Sno, Sname, Ssex, Sage, Sdept) 例3. 查询全体学生的全部信息。 SELECT Sno, Sname, Ssex, Sage, Sdept FROM Student; 等价于 SELECT * FROM Student; 2019/12/6 数据库原理
2019/12/6 数据库原理
3.查询经过计算的值 学生表:Student(Sno, Sname, Ssex, Sage, Sdept) 例4. 查询全体学生的姓名及其出生年份。 SELECT Sname, 2006- Sage FROM Student; 2019/12/6 数据库原理
例5. 查询全体学生的姓名、出生年份和所有系,要求用小写字母表示所有系名。 SELECT Sname, 'Year of Birth:', 2006- Sage, LOWER(Sdept) FROM Student; SELECT Sname NAME, 'Year of Birth:' BIRTH, 2006- Sage BIRTHDAY, ISLOWER(Sdept) DEPARTMENT FROM Student; 2019/12/6 数据库原理
2019/12/6 数据库原理
学生课程表:SC(Sno, Cno, Grade) 1.消除取值重复的行 学生课程表:SC(Sno, Cno, Grade) 例6. 查询选修了课程的学生学号。 SELECT Sno FROM SC; 消除重复的行 SELECT DISTINCT Sno FROM SC; 2019/12/6 数据库原理
2019/12/6 数据库原理
2. 查询满足条件的元组 Where 子句——运算符 比较:<、<=、>、>=、=、<>、!=、!>、!< not+上述比较运算符 确定范围:Between A and B、 Not Between A and B 确定集合:IN、NOT IN 字符匹配:LIKE、NOT LIKE 空值: IS NULL、IS NOT NULL 多重条件:AND、OR 2019/12/6 数据库原理
(1) 比较大小 例7. 查询计算机系全体学生的名单。 SELECT Sname FROM Student WHERE Sdept = 'CS'; 2019/12/6 数据库原理
2019/12/6 数据库原理
或 例8. 查询所有年龄在20岁以下的学生姓名及其年龄。 SELECT Sname, Sage FROM Student WHERE Sage < 20; 或 SELECT Sname, Sage FROM Student WHERE NOT Sage >= 20; 2019/12/6 数据库原理
2019/12/6 数据库原理
FROM SC WHERE Grade < 60; 例9. 查询考试成绩有不及格的学生的学号。 SELECT DISTINCT Sno FROM SC WHERE Grade < 60; 2019/12/6 数据库原理
2019/12/6 数据库原理
(2) 确定范围 例10. 查询年龄在20~23岁(包括20岁和23岁)之间的学 生的姓名、系别和年龄。 SELECT Sname, Sdept, Sage FROM Student WHERE Sage BETWEEN 20 AND 23; SELECT Sname, Sdept, Sage FROM Student WHERE Sage >= 20 AND Sage <= 23; 2019/12/6 数据库原理
2019/12/6 数据库原理
SELECT Sname, Sdept, Sage FROM Student 例11. 查询年龄不在20~23岁之间的学生姓名、系别 和年龄。 SELECT Sname, Sdept, Sage FROM Student WHERE Sage NOT BETWEEN 20 AND 23; SELECT Sname, Sdept, Sage FROM Student WHERE Sage < 20 OR Sage > 23; 2019/12/6 数据库原理
2019/12/6 数据库原理
(3) 确定集合 例12. 查询信息系(IS)、数学系(MA)和计算机科学系(CS)学生的姓名和性别。 SELECT Sname, Ssex FROM Student WHERE Sdept IN ('IS', 'MA', 'CS'); SELECT Sname, Ssex FROM Student WHERE Sdept = 'IS' OR Sdept = 'MA' OR Sdept = 'CS'; 2019/12/6 数据库原理
2019/12/6 数据库原理
例13.查询既不是信息系(IS)、数学系(MA)也不是计算机 科学系(CS)学生的姓名和性别。 SELECT Sname, Ssex FROM Student WHERE Sdept NOT IN ('IS', 'MA', 'CS'); SELECT Sname, Ssex FROM Student WHERE Sdept != 'IS' AND Sdept != 'MA' AND Sdept != 'CS'; 2019/12/6 数据库原理
2019/12/6 数据库原理
(4) 字符匹配 Where 子句——Like 格式: [NOT] LIKE '<匹配串>' [ESCAPE '<换码字符>'] % : 表示任意长度(长度≥0)的字符串。 _ : 表示单个的任意字符 ESCAPE'\' : 表示\为换码字符,匹配串中紧跟在\后面的字符‘%’或‘_’,被定义为普通字符(不作通配符用) 2019/12/6 数据库原理
如果LIKE后面的匹配串中不含通配符,则可以用=运算符取代LIKE谓词;用!=或<>取代NOT LIKE谓词。 例14. 查询学号为95001的学生的详细情况。 SELECT * FROM Student WHERE Sno LIKE '95001'; 如果LIKE后面的匹配串中不含通配符,则可以用=运算符取代LIKE谓词;用!=或<>取代NOT LIKE谓词。 等价于 SELECT * FROM Student WHERE Sno = '95001'; 2019/12/6 数据库原理
2019/12/6 数据库原理
例15. 查询所有姓王的学生的姓名、学号和性别。 SELECT Sname, Sno, Ssex FROM Student WHERE Sname LIKE '王%'; 2019/12/6 数据库原理
2019/12/6 数据库原理
例16. 查询姓李,且姓名为两个汉字的学生姓名。 SELECT Sname FROM Student WHERE Sname LIKE '李__ ' ; 一个汉字占两个字符的位置 2019/12/6 数据库原理
2019/12/6 数据库原理
例17. 查询名字中第二个字为“晨”字的学生姓名 和学号。 SELECT Sname, Sno FROM Student WHERE Sname LIKE '__晨% ' ; 2019/12/6 数据库原理
2019/12/6 数据库原理
WHERE Sname NOT LIKE '刘% ' ; 例18. 查询所有不姓刘的学生姓名。 SELECT Sname FROM Student WHERE Sname NOT LIKE '刘% ' ; 2019/12/6 数据库原理
2019/12/6 数据库原理
例19. 查询DB_Design课程的课程号和学分。 SELECT Cno, Ccredit FROM Course WHERE Cname LIKE 'DB\_Design' ESCAPE '\' ; 2019/12/6 数据库原理
例20. 查询以“DB_”开头,且倒数第三个字符为i的课程 的详细情况。 SELECT * FROM Course WHERE Cname LIKE 'DB\_%i__' ESCAPE'\'; 2019/12/6 数据库原理
(5) 涉及空值的查询 例21. 某些学生选修课后没有参加考试,所以有选课录, 但没有成绩。查询缺少成绩的学生的学号和相应 课程号。 SELECT Sno, Cno FROM SC WHERE Grade IS NULL ; 2019/12/6 数据库原理
2019/12/6 数据库原理
WHERE Grade IS NOT NULL ; 例22. 查询所有有成绩的学生学号和课程号。 SELECT Sno, Cno FROM SC WHERE Grade IS NOT NULL ; 2019/12/6 数据库原理
2019/12/6 数据库原理
(6) 多重条件查询 例23. 查询计算机系年龄在20岁以下的学生姓名。 SELECT Sname FROM Student WHERE Sdept = 'CS' AND Sage < 20 ; 2019/12/6 数据库原理
2019/12/6 数据库原理
逻辑运算符AND的优先级比OR高,可通过括号改变优先级。 例24.查询信息系(IS)、数学系(MA)和计算机科学系(CS)的 男学生的姓名和年龄。 SELECT Sname, Sage FROM Student WHERE ( Sdept = 'IS' OR Sdept = 'MA' OR Sdept = 'CS' ) AND Ssex = '男' ; 逻辑运算符AND的优先级比OR高,可通过括号改变优先级。 2019/12/6 数据库原理
2019/12/6 数据库原理
3. 对查询结果的排序 例25. 查询选修了3号课程的学生的学号及其成绩,查询 结果按分数的降序排列。 SELECT Sno, Grade FROM SC WHERE Cno = '3' ORDER BY Grade DESC; 2019/12/6 数据库原理
2019/12/6 数据库原理
例26. 查询全体学生情况,查询结果按所在系的系号升序 排列,同在一个系的按年龄降序排列。 SELECT * FROM Student ORDER BY Sdept ASC, Sage DESC; SELECT * FROM Student ORDER BY Sdept, Sage DESC; 2019/12/6 数据库原理
2019/12/6 数据库原理
4. 使用集函数 主要有: COUNT([DISTINCT|ALL] *) 统计元组个数 SUM([DISTINCT|ALL] <列名>) 计算一列值的总和(此列必须是数值型) AVG([DISTINCT|ALL] <列名>) 计算一列值的平均值(此列必须是数值型) MAX([DISTINCT|ALL] <列名>) 求一列值中的最大值 MIN([DISTINCT|ALL] <列名>) 求一列值中的最小值 2019/12/6 数据库原理
SELECT COUNT (DISTINCT Sno) FROM SC; 例27. 查询学生总人数。 SELECT COUNT (*) FROM Student; 例28. 查询选修了课程的学生人数。 SELECT COUNT (DISTINCT Sno) FROM SC; 2019/12/6 数据库原理
例29. 计算2号课程的学生平均成绩。 SELECT AVG(Grade) FROM SC WHERE Cno = '2' ; 例30. 查询选修2号课程的学生最高成绩。 SELECT MAX(Grade) FROM SC WHERE Cno = '2' ; 2019/12/6 数据库原理
2019/12/6 数据库原理
5. 对查询结果分组 例31. 求各个课程号及相应的选课人数。 SELECT Cno, COUNT(Sno) FROM SC GROUP BY Cno; 2019/12/6 数据库原理
HAVING COUNT(*) >= 3 ; 例32. 查询选修了3门以上课程的学生学号。 SELECT Sno FROM SC GROUP BY Sno HAVING COUNT(*) >= 3 ; HAVING用于分组后按一定条件对这些分组进行筛选。 WHERE子句作用于基本表或视图,从中选择满足条件的元组 HAVING短句作用于组,从中选择满足条件的组 2019/12/6 数据库原理
2019/12/6 数据库原理
3.3.2 连接查询 等值与非等值连接查询 自身连接 外连接 复合条件连接 2019/12/6 数据库原理
1. 等值与非等值连接查询 连接条件一: [<表名1>.]<列名1> <比较运算符> [<表名2>.]<列名2> 连接条件二: [<表名1>.]<列名1> BETWEEN [<表名2>.]<列名2> AND [<表名2>.]<列名3> 比较运算符主要有:=、>、<、>=、<=、!=。 连接查询中用来连接两个表的条件称为连接条件或连接谓词。 连接谓词中的列名称为连接字段,其各字段应是可比的。 2019/12/6 数据库原理
WHERE Student.Sno = SC.Sno ; 等值连接 例33. 查询每个学生及其选修课程的情况。 SELECT Student.*, SC.* FROM Student, SC WHERE Student.Sno = SC.Sno ; 等值连接 自然连接:在等值连接中把目标列中重复的属性列去掉。 SELECT Student.Sno, Sname, Ssex, Sage, Sdept, Cno, Grade FROM Student, SC WHERE Student.Sno = SC.Sno ; 2019/12/6 数据库原理
2019/12/6 数据库原理
2. 自身连接 例34. 查询每门课的间接先修课。 SELECT FIRST.Cno, SECOND.Cpno FROM Course FIRST , Course SECOND WHERE FIRST.Cpno = SECOND.Cno ; 一个表与其自身进行连接 2019/12/6 数据库原理
2019/12/6 数据库原理
3. 外连接 在连接条件的某侧加上(*) 或(+),表示该侧所对应的表中可形成一个各数据项均为空值的万能替代行,用来与另一侧对应的表中所有不满足条件的元组进行连接。外连接符(*)或(+)出现在左侧称为右外连接、出现在右侧称为左连接、两侧都出现的称为全外连接。 2019/12/6 数据库原理
SELECT Student.Sno, Sname, Ssex, Sage, Sdept, Cno, Grade 例35. 查询每个学生及其选修课的情况。 SELECT Student.Sno, Sname, Ssex, Sage, Sdept, Cno, Grade FROM SC RIGHT JOIN Student ON Student.Sno = SC.Sno; 2019/12/6 数据库原理
2019/12/6 数据库原理
4. 复合条件连接 例36. 查询选修了2号课程且成绩在90分以上的所有学生。 SELECT Student.Sno, Sname FROM Student, SC WHERE Student.Sno = SC.Sno AND SC.Cno = '2' AND SC.Grade >= 90 ; WHERE子句中有多个连接条件 2019/12/6 数据库原理
例37. 查询每个学生的学号、姓名、选修课程名及成绩。 SELECT Student.Sno, Sname, Cname, Grade FROM Student, SC, Course WHERE Student.Sno = SC.Sno AND SC.Cno = Course.Cno; 多表连接 2019/12/6 数据库原理
2019/12/6 数据库原理
3.3.3 嵌套查询 在SQL语言中,一个SELECT-FROM-WHERE语句称为一个查询块。一个查询块嵌套在另一个查询块的WHERE子句或HAVING短语的条件中的查询称为嵌套查询。例如: SELECT Sname FROM Student WHERE Sno IN SELECT Sno FROM SC WHERE Cno = '2' ; 外层查询 不能使用ORDER BY子句 内层查询 2019/12/6 数据库原理
3.3.3 嵌套查询 带有IN谓词的子查询 带有比较运算符的子查询 带有ANY或ALL谓词的子查询 带有EXISTS谓词的子查询 2019/12/6 数据库原理
1.带有IN谓词的子查询 或 例38. 查询与“刘晨”在同一个系学习的学生。 SELECT Sno, Sname, Sdept FROM Student WHERE Sdept IN (SELECT Sdept FROM Student WHERE Sname= '刘晨'); (2)其次在Student关系中找出'IS'系的学生 (1)首先在Student关系中找出刘晨所在的系,结果为'IS '。 或 SELECT S1.Sno, S1.Sname, S1.Sdept FROM Student S1, Student S2 WHERE S1.Sdept = S2.Sdept AND S2.Sname = '刘晨'; 2019/12/6 数据库原理
2019/12/6 数据库原理
或 例39. 查询选修了课程名为“信息系统”的学生学号和姓名。 SELECT Sno, Sname FROM Student WHERE Sno IN (SELECT Sno FROM SC WHERE Cno IN (SELECT Cno FROM Course WHERE Cname = '信息系统')); (3)最后在Student关系中取出学号和姓名。 (2)其次在SC关系中找出选修3号课程的学生 (1)首先在Course关系中找出“信息系统的课程号”,结果为3。 或 SELECT Sno, Sname FROM Student, SC, Course WHERE Student.Sno = SC.Sno AND SC.Cno = Course.Cno AND Course.Cname = '信息系统' ; 2019/12/6 数据库原理
2019/12/6 数据库原理
2.带有比较运算符的子查询 例40. 查询与“刘晨”在同一个系学习的学生。 SELECT Sno, Sname, Sdept FROM Student WHERE Sdept = (SELECT Sdept FROM Student WHERE Sname = '刘晨'); 内存查询返回的是单值时,可以用比较运算符;子查询要跟在比较符之后。 2019/12/6 数据库原理
2019/12/6 数据库原理
3.带有ANY或ALL谓词的子查询 子查询返回单值时可以用比较运算符,而使用ANY或ALL谓词时必须同时使用比较运算符。其语义为: 2019/12/6 数据库原理
或 例41. 查询其他系中比信息系某一学生年龄小的学生姓名和年龄。 SELECT Sname, Sage FROM Student WHERE Sage <ANY (SELECT Sage FROM Student WHERE Sdept = 'IS') AND Sdept <> 'IS '; 或 SELECT Sname, Sage FROM Student WHERE Sage < (SELECT MAX(Sage) FROM Student WHERE Sdept = 'IS ') AND Sdept<> 'IS '; 2019/12/6 数据库原理
2019/12/6 数据库原理
或 例42. 查询其他系中比信息系所有学生年龄小的学生姓名和年龄。 SELECT Sname, Sage FROM Student WHERE Sage <ALL (SELECT Sage FROM Student WHERE Sdept = 'IS') AND Sdept <> 'IS'; 或 SELECT Sname, Sage FROM Student WHERE Sage < (SELECT MIN(Sage) FROM Student WHERE Sdept = 'IS') AND Sdept <> 'IS'; 2019/12/6 数据库原理
= 集函数实现子查询比直接用ANY或ALL查询效率更高。 表3-4 ANY, ALL谓词与集函数及IN谓词的等价转换关系 <>或!= < <= > >= ANY IN __ <MAX <=MAX >MIN >=MIN ALL NOT IN <MIX <=MIN >MAX 2019/12/6 数据库原理
4.带有EXISTS谓词的子查询 不相关子查询: 子查询的查询条件不依赖于父查询的子查询。 相关子查询(Correlated Subquery): 子查询的查询条件依赖于外层父查询的某个属性值的子查询。 带EXISTS 的子查询就是相关子查询 EXISTS表示存在量词 带有EXISTS的子查询不返回任何记录的数据,只返回逻辑值 'True' 或 'False' 2019/12/6 数据库原理
例43-1. 查询所有选修了1号课程的学生姓名。 SELECT Sname FROM Student WHERE Sno IN (SELECT SNO FROM SC WHERE SC.Cno= '1'); 不相关子查询 2019/12/6 数据库原理
WHERE Sno=Student.Sno AND Cno= '1'); 例43-2. 查询所有选修了1号课程的学生姓名。 SELECT Sname FROM Student WHERE EXISTS (SELECT * FROM SC WHERE Sno=Student.Sno AND Cno= '1'); 相关子查询 执行过程: 先在外层查询中取Student表的第一个元组,用该元组的相关的属性值(在内层WHERE子句中给定的)处理内层查询,若外层的WHERE子句返回'TRUE'值,则此元组送入结果的表中。然后再取下一个元组;重复上述过程直到外层表的元组全部遍历一次为止。 2019/12/6 数据库原理
2019/12/6 数据库原理
说明: 不关心子查询的具体内容,因此用 SELECT * Exists + 子查询用来判断该子查询是否返回元组 当子查询的结果集非空时,Exists 为 'True' 当子查询的结果集为空时,Exists 为 'False' NOT EXISTS :若子查询结果为空,返回'TRUE'值, 否则返回 'FALSE' 2019/12/6 数据库原理
WHERE Sno=Student.Sno AND Cno= '1'); 或 SELECT Sname FROM Student 例44. 查询没有选修1号课程的学生姓名。 SELECT Sname FROM Student WHERE NOT EXISTS (SELECT * FROM SC WHERE Sno=Student.Sno AND Cno= '1'); 或 SELECT Sname FROM Student WHERE Sno NOT IN (SELECT SNO WHERE SC.Cno= '1'); 相关子查询 不相关子查询 2019/12/6 数据库原理
2019/12/6 数据库原理
WHERE S1.Sdept=S2.Sdept AND S2.Sname= '刘晨'); 或 FROM Student 例45. 查询与刘晨在同一个系学习的学生。 SELECT Sno, Sname, Sdept FROM Student S1 WHERE EXISTS (SELECT * FROM Student S2 WHERE S1.Sdept=S2.Sdept AND S2.Sname= '刘晨'); 或 FROM Student WHERE Sdept IN (SELECT Sdept FROM Student WHERE Sname= '刘晨'); 2019/12/6 数据库原理
2019/12/6 数据库原理
WHERE Sno=Student.Sno AND Cno=Course.Cno)); 例46. 查询选修了全部课程的学生姓名。 SELECT Sname FROM Student WHERE NOT EXISTS (SELECT * FROM Course WHERE NOT EXISTS FROM SC WHERE Sno=Student.Sno AND Cno=Course.Cno)); 这样的课是不存在的 这门课他没选 2019/12/6 数据库原理
2019/12/6 数据库原理
例47. 查询至少选修了学生95002选修的全部课程的学生号。 SELECT DISTINCT Sno FROM SC SCX WHERE NOT EXISTS (SELECT * FROM SC SCY WHERE SCY.Sno= '95002' AND NOT EXISTS FROM SC SCZ WHERE SCZ.Sno=SCX.Sno AND SCZ.Cno=SCY.Cno)); 2019/12/6 数据库原理
3.3.4 集合查询 例48. 查询计算机系的学生或者年龄不大于19岁的学生。 SELECT * FROM Student WHERE Sdept = 'CS' UNION WHERE Sage <= 19 2019/12/6 数据库原理
2019/12/6 数据库原理
例49. 查询选修了课程1或选修课程2的学生。 SELECT Sno FROM SC WHERE Cno = '1' UNION 2019/12/6 数据库原理
2019/12/6 数据库原理
例50. 查询计算机系的学生与年龄不大于19岁的学生的交集。 SELECT * FROM Student WHERE Sdept = 'CS' AND Sage <=19; 例51. 查询选修了课程1的学生集合与选修课程2的学生集合的 交集。 SELECT Sno FROM SC WHERE Cno= '1' AND Sno IN (SELECT Sno FROM SC WHERE Cno= '2'); 2019/12/6 数据库原理
例52. 查询计算机系的学生与年龄不大于19岁的学生的差集。 SELECT * FROM Student WHERE Sdept = 'CS' AND Sage >19; 例53. 查询选修课程1但没有选修课程2的学生。 SELECT Sno FROM SC WHERE Cno= '1' AND Sno NOT IN (SELECT Sno FROM SC WHERE Cno= '2'); 2019/12/6 数据库原理
3.3.5 SELECT语句的一般格式 SELECT [ALL|DISTINCT]<目标列表达式>[别名][,<目标列表达式>[别名]]…… FROM <表名或视图名>[别名][,<表名或视图名>[别名]]…… [WHERE <条件表达式>] [GROUP BY<列名1>[HAVING<条件表达式>]] [ORDER BY<列名2>[ASC|DESC]]; 2019/12/6 数据库原理
3.4 数据更新 插入操作 INSERT 修改操作 UPDATE 删除操作 DELETE 2019/12/6 数据库原理
格式:INSERT INTO <表名>[(<列名1>[,<列名2>]…)] 3.4.1 插入数据 1.插入单个元组 格式:INSERT INTO <表名>[(<列名1>[,<列名2>]…)] VALUES (<常量1>[,<常量2>]…); 插入一已知元组的全部列的常量 插入一已知元组的部分列的常量 表定义时说明了NOT NULL的属性列不能取空值 如果INTO子句没有指明任何列名,则新插入的记录必须在 每个属性列上均有值。 2019/12/6 数据库原理
INSERT INTO SC(Sno,Cno) VALUES ('95005', '1'); 插入一已知元组的全部列常量 例1:将一个新生记录插入学生表。 INSERT INTO Student VALUES('95005', '陈冬', '男',18, 'CS'); 插入一已知元组的部分列常量 例2:新增一条选课记录 INSERT INTO SC(Sno,Cno) VALUES ('95005', '1'); 2019/12/6 数据库原理
2019/12/6 数据库原理
格式:INSERT INTO <表名>[(<列名1>[,<列名2>]…)] 子查询; 2.插入子查询结果 格式:INSERT INTO <表名>[(<列名1>[,<列名2>]…)] 子查询; 例3:对每个系,求学生的平均年龄,并把结果存入数据库。 CREATE TABLE Deptage (Sdept CHAR(15) Avgage SMALLINT); INSERT INTO Deptage(Sdept, Avgage) SELECT Sdept, AVG(Sage) FROM Student GROUP BY Sdept; 2019/12/6 数据库原理
2019/12/6 数据库原理
SET <列名>=<表达式> [, <列名>=<表达式> ]… 3.4.2 修改数据 格式: UPDATE <表名> SET <列名>=<表达式> [, <列名>=<表达式> ]… [WHERE <条件>]; 2019/12/6 数据库原理
1.修改某一个元组的值 例4:将学生95001的年龄改为22。 UPDATE Student SET Sage = 22 WHERE Sno = '95001'; 2.修改多个元组的值 例5:将所有学生的年龄都增加1。 UPDATE Student SET Sage = Sage+1; 2019/12/6 数据库原理
2019/12/6 数据库原理
3.带子查询的修改语句 例6:将计算机科学系学生的成绩都置零。 UPDATE SC SET Grade = 0 WHERE Sno IN (SELECT Sno FROM Student WHERE Sdept ='CS'); 2019/12/6 数据库原理
2019/12/6 数据库原理
3.4.3 删除数据 格式: DELETE FROM <表名> [WHERE <条件>]; 只能对整个元组操作,不能只删除某些属性上的值。 只能对一个关系起作用,若要从多个关系中删除元组, 则必须对每个关系分别执行删除命令。 从关系R中删除满足P的元组,只是删除数据,而不是定义。 2019/12/6 数据库原理
1.删除某一个元组的值 例7:删除学号为95005的学生记录。 DELETE FROM Student WHERE Sno= '95005'; 2.删除多个元组的值 例8:删除所有的学生选课记录。 DELETE FROM SC; 2019/12/6 数据库原理
3.带子查询的删除语句 例9:删除计算机科学系所有学生的选课记录。 DELETE FROM SC WHERE Sno IN (SELECT Sno FROM Student WHERE Sdept= 'CS'); 2019/12/6 数据库原理
4.更新操作与数据库的一致性 例10:删除学号为95005的学生记录。 首先 DELETE FROM SC 删除表中元组的策略: (1)自动删除参照表中相应的元组; (2)检查参照表中是否存在相应的元组,如果存在相应的元组,如果存在,则操作失败。 首先 DELETE FROM SC WHERE Sno= '95005'; 其次 FROM Student 事务(Transaction):保证语句要么都做,要么都不做,以保证关系的完整性。 2019/12/6 数据库原理
3.5 视 图 视图是从一个或几个表(或视图)导出的表。 视图是一个虚表 数据库中只存放视图的定义 视图对应的数据仍存放在原来的表中 3.5 视 图 视图是从一个或几个表(或视图)导出的表。 视图是一个虚表 数据库中只存放视图的定义 视图对应的数据仍存放在原来的表中 随着表中数据的变化,视图的数据随之改变。 对视图的查询与基本表一样 对视图的更新将受到一定的限制 2019/12/6 数据库原理
3.5 视 图 定义视图 查询视图 更新视图 视图的作用 2019/12/6 数据库原理
3.5.1 定义视图 视图概念 视图 视图是一个虚表 数据库中只存放视图的定义 视图对应的数据仍存放在原来的表中 随着表中数据的变化,视图的数据随之改变。 对视图的查询与基本表一样 对视图的更新将受到一定的限制 基本表1 基本表2 视图概念示意图 2019/12/6 数据库原理
格式:CREATE VIEW <视图名>[(<列名>[,<列名>]…)] AS 子查询 建立视图 格式:CREATE VIEW <视图名>[(<列名>[,<列名>]…)] AS 子查询 [WITH CHECK OPTION]; 下述必须指定全部列名: 某个目标列是集函数或表达式 多表连接时,目标列中出现同名列 需在视图中为某列用新的名字 在定义视图时要么指定全部视图列,要么全部省略不写;如果省略了视图的属性列名,则视图的列名与子查询列名相同。 子查询中通常不包含ORDER BY和DISTINCT子句。 WITH CHECK OPTION:对视图进行UPDATE、INSERT、DELETE操作时要保证 更新、插入或删除的行满足视图定义中的谓词条件。 2019/12/6 数据库原理
行列子集视图:从单个基本表导出,保留基本表的码, 但去掉其它的某些列和部分行的视图。 表达式视图:带虚拟列(经过各种计算派生出的数据 视图分类 行列子集视图:从单个基本表导出,保留基本表的码, 但去掉其它的某些列和部分行的视图。 表达式视图:带虚拟列(经过各种计算派生出的数据 所设置的派生属性列)的视图。 分组视图 : 子查询目标表带有组函数或子查询带有 GROUP BY子句的视图。 2019/12/6 数据库原理
CREATE VIEW IS_Student AS SELECT Sno,Sname,Ssex,Sage FROM Student 例1:建立信息系学生视图 CREATE VIEW IS_Student AS SELECT Sno,Sname,Ssex,Sage FROM Student WHERE Sdept= 'IS'; (行列子集视图) 建立视图的结果是把视图定义存入数据字典,并不执行SELECT语句;只在对视图查询时,才按其定义从基本表中将数据查出。 2019/12/6 数据库原理
例2:建立计算机系学生视图,并要求进行修改和插入操作时仍需保证该视图只有计算机系的学生。 CREATE VIEW CS_Student AS SELECT Sno,Sname,Ssex,Sage FROM Student WHERE Sdept= 'CS' WITH CHECK OPTION; 由于加上了WITH CHECK OPTION子句,以后对该视图进行插入、修改、删除操作时,DBMS会自动加上Sdept=‘CS’的条件。 2019/12/6 数据库原理
例3:建立信息系选修了1号课程的学生的视图。 CREATE VIEW IS_S1(Sno,Sname,Grade) AS SELECT Student.Sno,Sname,Grade FROM Student, SC WHERE Sdept= 'IS'AND SC.Cno= '1' AND Student.Sno=SC.Sno; 建立在多个基本表上 2019/12/6 数据库原理
例4:建立信息系选修了1号课程且成绩在90分以上的 学生的视图。 CREATE VIEW IS_S2 AS SELECT Sno,Sname,Grade FROM IS_S1 WHERE Grade>=90; 建立在已定义的视图上 2019/12/6 数据库原理
CREATE VIEW BT_S(Sno, Sname, Sbirth) AS SELECT Sno,Sname,2006-Sage 例5:定义一个反映学生出生年份的视图。 CREATE VIEW BT_S(Sno, Sname, Sbirth) AS SELECT Sno,Sname,2006-Sage FROM Student; (表达式视图) 虚拟列 2019/12/6 数据库原理
例6:将学生的学号及他的平均成绩定义为一个视图。 CREATE VIEW S_G(Sno, Gavg) AS SELECT Sno,AVG(Grade) FROM SC GROUP BY Sno; (分组视图) 2019/12/6 数据库原理
例7:将Student表中所有女生记录定义为一个视图。 CREATE VIEW F_Student(stdnum, name, sex, age, dept) AS SELECT * FROM Student WHERE Ssex= '女'; 如果修改了基本表Student的结构,则视图与基本表之间的映象关系被破坏,视图就不能正确工作。为避免出现该类问题,最好在修改基本表之后删除有该基本表导出的视图,然后重建(同名)视图。 2019/12/6 数据库原理
格式:DROP VIEW <视图名>; 删除视图 格式:DROP VIEW <视图名>; 例8:删除视图IS_S1。 DROP VIEW IS_S2; (IS_S2由IS_S1导出) DROP VIEW IS_S1; 2019/12/6 数据库原理
3.5.2 查询视图 视图消解 (View Resolution) 在对视图查询时,DBMS将进行有效性检查(表及视图)。若存在,则从数据字典中取出视图定义,并把定义中的子查询与用户查询结合起来转换为等价的对基本表的查询,然后再执行。 2019/12/6 数据库原理
例1:在信息系学生的视图中查找年龄小于20的学生。 SELECT Sno,Sname FROM IS_Student WHERE Sage < 20; 视图消解 SELECT Sno,Sname FROM Student WHERE Sage<20 AND Sdept= 'IS'; 2019/12/6 数据库原理
WHERE SC.Sno=IS_Student.Sno AND SC.Cno= '1'; 例2:查询信息系选修了1号课程的学生。 SELECT Sno,Sname FROM IS_Student, SC WHERE SC.Sno=IS_Student.Sno AND SC.Cno= '1'; 视图消解 SELECT Sno,Sname FROM Student,SC WHERE SC.Cno= '1' AND Sdept= 'IS' Student.Sno=SC.Sno; 2019/12/6 数据库原理
例3:在S_G视图中查询平均成绩在90分以上的学生学号和 平均成绩。 SELECT * FROM S_G WHERE Gavg >= 90; (系统转换后) SELECT Sno,AVG(Grade) FROM SC WHERE AVG(Grade) >= 90 GROUP BY Sno; SELECT Sno,AVG(Grade) FROM SC GROUP BY Sno; 2019/12/6 数据库原理
例3:在S_G视图中查询平均成绩在90分以上的学生学号和 平均成绩。 SELECT * FROM S_G WHERE Gavg >= 90; (系统转换后) SELECT Sno,AVG(Grade) FROM SC GROUP BY Sno HAVING AVG(Grade) >= 90 ; 2019/12/6 数据库原理
3.5.3 更新视图 更新视图即通过视图插入(INSERT)、删除(DELETE)和修改(UPDATE)数据,实质上转换为对基本表的更新。 为了防止用户对超出视图范围的基本表的数据进行操作,在定义视图时,应加上WITH CHECK OPTION子句,则在视图上更新数据时,DBMS将检查视图定义中的条件,不满足将拒绝执行。 2019/12/6 数据库原理
例1:将信息系学生视图IS_Student中学号为95002的学生的姓名改为“刘辰”。 UPDATE IS_Student SET Sname= '刘辰' WHERE Sno = '95002'; (系统转换后) UPDATE Student SET Sname= '刘辰' WHERE Sno = '95002' AND Sdept= 'IS'; 2019/12/6 数据库原理
例2:向信息系学生视图IS_Student中插入一名新生,学号为95006,姓名为赵新,年龄为20岁的学生。 INSERT INTO IS_Student VALUES ('95006', '赵新',20); (系统转换后) INSERT INTO Student(Sno, Sname, Sage, Sdept) VALUES ('95006', '赵新',20, 'IS'); 2019/12/6 数据库原理
例3:删除信息系学生视图IS_Student中学号为95006的 记录。 DELETE FROM IS_Student WHERE Sno= '95006'; (系统转换后) DELETE FROM Student WHERE Sno= '95006' AND Sdept= 'IS'; 2019/12/6 数据库原理
视图的列来自表达式或常数,不可插入、修改、可删除 视图列是来自集函数,不可更新 视图定义中含有GROUP BY子句,不可更新 一般情况下,行列子集视图是可更新的。 不可更新的视图(各系统不太一致) 由多个表导出的视图,不可更新 视图的列来自表达式或常数,不可插入、修改、可删除 视图列是来自集函数,不可更新 视图定义中含有GROUP BY子句,不可更新 视图定义中含有DISTINCT短语,不可更新 视图定义中内层嵌套的表与导出该视图表相同,不可更新 在不允许更新的视图上定义的视图,不可更新 2019/12/6 数据库原理
例: 将SC中成绩在平均成绩之上的元组定义成一个视图 GOOD_SC。 CREATE VIEW GOOD_SC AS SELECT Sno, Cno, Grade FROM SC WHERE Grade > (SELECT AVG(Grade) FROM SC); 2019/12/6 数据库原理
3.5.4 视图的作用 视图能够简化用户的操作 使数据库看起来结构简单、清晰、可简化用户的数据查询操作 视图使用户能以多种角度看待同一数据 使不同的用户以不同的方式看待同一数据 视图对重构数据库提供了一定程度的逻辑独立性 视图能够对机密数据提供安全保护 对不同的用户定义不同的视图,使机密数据不出现在不应看到这些数据的用户的视图上。 2019/12/6 数据库原理
3.6 数据控制 支持事物、提交、回滚等。 数据库恢复、并发控制 某用户对某类数据具有何种操作权力。 把授权决定告知系统 把授权结果存入数据字典 用户提出操作请求,根据授权情况决定是否执行请求 数据控制功能 数据库的安全性控制 数据库的完整性控制 定义码、取值唯一的列、不为空值的列、外码及其他一些约束条件。 2019/12/6 数据库原理
3.6.1 授 权 表3.4 不同对象类型允许的操作权限 对 象 对象类型 操作权限 属性列 TABLE SELECT, INSERT, UPDATE, DELETE, ALL PRIVILEGES 视 图 基本表 DELETE, ALTER, INDEX, ALL PRIVILEGES 数据库 DATABASE CREATETAB 2019/12/6 数据库原理
格式: GRANT <权限> [, <权限> ]…… [ON <对象类型><对象名>] [WITH GRANT OPTION]; WITH GRANT OPTION允许用户转授权(权限传播) 接受权限的用户可以是一个或多个用户,也可以是 PUBLIC(全体用户)。 2019/12/6 数据库原理
DATABASE: 格式: GRANT CREATETAB ON DATABASE <数据库名> TO <用户>[,<用户>]…… [WITH GRANT OPTION]; 建立表的权限属于DBA,可由DBA授权普通用户,普通用户拥有此权限后可建立基本表,基本表的属主拥有对该表的一切操作权限。 2019/12/6 数据库原理
TABLE级的基本表: 格式: GRANT [SELECT|INSERT|UPDATE|DELETE |ALTER|INDEX|ALL PRIVILEGES] ON TABLE <表名> TO <用户>[,<用户>]…… [WITH GRANT OPTION]; 由拥有该表的用户授予其他用户对表的操作权限。 2019/12/6 数据库原理
TABLE级的视图: 格式: GRANT [SELECT|INSERT|UPDATE| DELETE|ALL PRIVILEGES] ON TABLE <视图名> TO <用户>[,<用户>]…… [WITH GRANT OPTION]; 由拥有该视图的用户授予其他用户对本视图的操作权限。 2019/12/6 数据库原理
TABLE级的列: 格式: GRANT [SELECT|INSERT|UPDATE| DELETE|ALL PRIVILEGES] <列名>[,<列名>]…… ON TABLE <表或视图名> TO <用户>[,<用户>]…… [WITH GRANT OPTION]; 由拥有该表或视图的用户授予其他用户对列的操作权限。 2019/12/6 数据库原理
例1:把查询Student表的权限授给用户U1。 GRANT SELECT ON TABLE Student TO U1; 例2:把对Student表和Course表的全部操作权限授给用户 U2和U3。 GRANT ALL PRIVILEGES ON TABLE Student, Course TO U2, U3; 2019/12/6 数据库原理
例4:把查询Student表和修改学生学号的权限授予用户U4。 GRANT UPDATE(Sno),SELECT 例3:把对表SC的查询权限授予所有用户。 GRANT SELECT ON TABLE SC TO PUBLIC; 例4:把查询Student表和修改学生学号的权限授予用户U4。 GRANT UPDATE(Sno),SELECT ON TABLE Student TO U2, U4; 2019/12/6 数据库原理
例5:把对表SC的INSERT权限授予用户U5,并允许将此权限 再授予其他用户。 GRANT INSERT ON TABLE SC TO U5 WITH GRANT OPTION; 用户U5可将此权限再授予其他用户,例如: GRANT INSERT ON TABLE SC TO U6 WITH GRANT OPTION; GRANT INSERT ON TABLE SC TO U7; U7用户不能再传播此权限 U6用户还可再将此权限授权其他用户 2019/12/6 数据库原理
例6:DBA把在数据库S_C中建立表的权限授予用户U8。 GRANT CREATETAB ON DATABASE S_C TO U8; 2019/12/6 数据库原理
3.6.2 收回权限 授予的权限可由DBA或其他授权者用REVOKE语句收回。 格式1:REVOKE CREATETAB ON DATABASE <数据库名> FROM <用户>[,<用户>]……; 格式2:REVOKE <权限>[,<权限>]…… [ON TABLE <表名|视图名> 2019/12/6 数据库原理
例7. 把用户U4修改学生学号的权限收回 REVOKE UPDATE(Sno) ON TABLE Student FROM U4; 例8. 收回所有用户对表SC的查询权限 REVOKE SELECT ON TABLE SC FROM PUBLIC; 2019/12/6 数据库原理
例9. 把用户U5对SC表的INSERT权限收回 REVOKE INSERT ON TABLE SC FROM U5; DBMS在收回U5对表SC的INSERT权限时,还会收回U6和U7对SC表的INSERT权限,即收回权限的操作会级联下去。 如U6和U7还从其他用户获得对表SC的INSERT权限,则他们仍具有此权限,系统只收回直接或间接从U5处获得的权限。 2019/12/6 数据库原理
3.7 嵌入式SQL SQL语言提供了两种不同的使用方式: 交互式 嵌入式 为什么要引入嵌入式SQL SQL语言是非过程性语言 事务处理应用需要高级语言 这两种方式细节上有差别,在程序设计的环境下,SQL语句要做某些必要的扩充 2019/12/6 数据库原理
嵌入式SQL 将SQL语言嵌入到某种高级语言中使用,利用高级语言的过程性结构来弥补SQL语言实现复杂应用方面的不足。 这种方式下使用的SQL语言称为嵌入式SQL(Embedded SQL)。 嵌入SQL的高级语言称为主语言或宿主语言。 2019/12/6 数据库原理
3.7 嵌入式SQL 嵌入式SQL的一般形式 嵌入式SQL语句与主语句之间的通信 不用游标的SQL语句 使用游标的SQL语句 动态SQL简介 2019/12/6 数据库原理
3.7.1 嵌入式SQL的一般形式 为了区分SQL语句与主语言语句,需要: 前缀:EXEC SQL 结束标志:随主语言的不同而不同 EXEC SQL <SQL语句> ; 例:EXEC SQL DROP TABLE Student ; 以COBOL作为主语言的嵌入式SQL语句的一般形式 EXEC SQL <SQL语句> END-EXEC 例: EXEC SQL DROP TABLE Student END-EXEC 2019/12/6 数据库原理
嵌入SQL语句 说明性语句 可执行语句 数据控制 数据定义 数据操纵 2019/12/6 数据库原理
3.7.2 嵌入式SQL语句与主语句之间的通信 1. SQL通信区(SQL Communication Area, SQLCA) 主语言能够据此控制程序流程 2. 主变量(Host Variable) 1)主语言向SQL语句提供参数 2)将SQL语句查询数据库的结果交主语言进一步处理 3. 游标(Cursor) 解决集合性操作语言与过程性操作语言的不匹配 2019/12/6 数据库原理
DBMS工作状态、运行信息SQLCA应用程序后继语句 SQLCA: SQL Communication Area SQLCA是一个数据结构 SQLCA的用途 SQL语句执行后,DBMS反馈给应用程序信息 描述系统当前工作状态 描述运行环境 这些信息将送到SQL通信区SQLCA中 应用程序从SQLCA中取出这些状态信息,据此决定接下来执行的语句 DBMS工作状态、运行信息SQLCA应用程序后继语句 2019/12/6 数据库原理
1. SQL 通信区 SQLCA的使用方法 SQL语句执行后,DBMS反馈给应用程序信息 描述系统当前工作状态 描述运行环境 2019/12/6 数据库原理
EXEC SQL INCLUDE SQLCA 加以定义 SQLCODE:SQLCA中的一个存放返回代码的变量;每次SQL语句执行后均返回一个值,表示该SQL语句执行是否成功,以及不成功的原因。 通常用预定义的常量SUCCESS表示成功;否则在SQLCODE中将存放错误代码。 2019/12/6 数据库原理
1. SQL 通信区 SQLCA的内容 与所执行的SQL语句有关 与该SQL语句的执行情况有关 例:在执行删除语句DELETE后,不同的执行情况,SQLCA中有不同的信息: 成功删除,并有删除的行数(SQLCODE=SUCCESS) 无条件删除警告信息 违反数据保护规则,操作拒绝 没有满足条件的行,一行也没有删除 由于各种原因,执行出错 2019/12/6 数据库原理
什么是主变量 2. 主变量 嵌入式SQL语句中可以使用主语言的程序变量来输入或输出数据 在SQL语句中使用的主语言程序变量简称为主变量(Host Variable) 2019/12/6 数据库原理
主变量的类型 2. 主变量 输入主变量 由应用程序对其赋值,SQL语句引用 输出主变量 由SQL语句赋值或设置状态信息,返回给应用程序 一个主变量有可能既是输入主变量又是输出主变量 2019/12/6 数据库原理
主变量的用途 2. 主变量 输入主变量 输出主变量 指定向数据库中插入的数据 将数据库中的数据修改为指定值 指定执行的操作 指定WHERE子句或HAVING子句中的条件 输出主变量 获取SQL语句的结果数据 获取SQL语句的执行状态 2019/12/6 数据库原理
指示变量 2. 主变量 一个主变量可以附带一个指示变量(Indicator Variable) 什么是指示变量 指示变量的用途 整型变量 用来“指示”所指主变量的值或条件 指示变量的用途 输入主变量可以利用指示变量赋空值 输出主变量可以利用指示变量检测出是否空值,值是否被截断 2019/12/6 数据库原理
EXEC SQL BEGIN DECLARE SECTION 2. 主变量 定义主变量: EXEC SQL BEGIN DECLARE SECTION ......... ......... (说明主变量和指示变量) EXEC SQL END DECLARE SECTION 引用主变量: 在SQL语句中引用主变量和指示变量时,其变量名前应加‘:’ ,主变量要紧跟在所指主变量之后。 2019/12/6 数据库原理
为什么要使用游标(Cursor) 3. 游 标 SQL语言与主语言具有不同数据处理方式 SQL语言是面向集合的,一条SQL语句原则上可以产生或处理多条记录 主语言是面向记录的,一组主变量一次只能存放一条记录 2019/12/6 数据库原理
什么是游标 3. 游 标 游标是系统为用户开设的一个数据缓冲区,存放SQL语句的执行结果 每个游标区都有一个名字 2019/12/6 数据库原理
实 例 例:带有嵌入式SQL的一小段C程序 ............ EXEC SQL INCLUDE SQLCA; EXEC SQL BEGIN DECLARE SECTION; /* (2) 说明主变量 */ CHAR Sno(5); CHAR Cno(3); INT Grade; EXEC SQL END DECLARE SECTION; /* 主变量说明结束 */ 2019/12/6 数据库原理
EXEC SQL DECLARE C1 CURSOR FOR /* (3) 游标操作(定义游标)*/ main() { EXEC SQL DECLARE C1 CURSOR FOR /* (3) 游标操作(定义游标)*/ SELECT Sno, Cno, Grade FROM SC; /* 从SC表中查询Sno, Cno, Grade*/ EXEC SQL OPEN C1; /* (4) 游标操作(打开游标)*/ for(;;) EXEC SQL FETCH C1 INTO :Sno, :Cno, :Grade; /* (5) 游标操作(推进游标指针并将当前数据放入主变量)*/ if (sqlca.sqlcode <> SUCCESS) /* (6) 利用SQLCA中的状态信息决定何时退出循环 */ break; printf(“Sno:%s, Cno:%s, Grade:%d", :Sno, :Cno, :Grade); /* 打印查询结果 */ } EXEC SQL CLOSE C1; /* (7) 游标操作(关闭游标)*/ 2019/12/6 数据库原理
不用游标的SQL语句的种类 3.7.3 不用游标的SQL语句 说明性语句 数据定义语句 数据控制语句 查询结果为单记录的SELECT语句 非CURRENT形式的UPDATE语句 非CURRENT形式的DELETE语句 INSERT语句 2019/12/6 数据库原理
说明性语句是专为在嵌入式SQL中说明主变量、SQLCA等而设置的 说明主变量 1. EXEC SQL BEGIN DECLARE SECTION; 2. EXEC SQL END DECLARE SECTION; 这两条语句必须配对出现,相当于一个括号,两条语句中间是主变量的说明 说明SQLCA 3. EXEC SQL INCLUDE SQLCA 2019/12/6 数据库原理
数据定义语句 例1. 建立一个“学生”表Student EXEC SQL CREATE TABLE Student (Sno CHAR(5) NOT NULL UNIQUE, Sname CHAR(20), Ssex CHAR(1), Sage INT, Sdept CHAR(15)); 数据定义语句中不允许使用主变量 例:下列语句是错误的 EXEC SQL DROP TABLE :table_name; 应为:EXEC SQL DROP TABLE Student; 2019/12/6 数据库原理
EXEC SQL GRANT SELECT ON TABLE Student TO U1; 数据控制语句 例2. 把查询Student表权限授给用户U1 EXEC SQL GRANT SELECT ON TABLE Student TO U1; 2019/12/6 数据库原理
语句格式 查询结果为单记录的SELECT语句 EXEC SQL SELECT [ALL|DISTINCT] <目标列表达式>[,<目标列表达式>]... INTO <主变量>[<指示变量>] [,<主变量>[<指示变量>]]... FROM <表名或视图名>[,<表名或视图名>] ... [WHERE <条件表达式>] [GROUP BY <列名1> [HAVING <条件表达式>]] [ORDER BY <列名2> [ASC|DESC]]; 2019/12/6 数据库原理
查询结果为单记录的SELECT语句 INTO子句、WHERE子句的条件表达式、HAVING短语的条件表达式中均可使用主变量; 查询返回记录中,某些列可能为空值NULL。如果INTO子句中主变量后面跟有指示变量,则当空值时,系统会自动将相应主变量后面的指示变量置为负值; 如果数据库中没有满足条件的记录,则DBMS将SQLCODE的值置为100; 如果查询结果实际上并不是单条记录,而是多条记录,则程序出错,DBMS会在SQLCA中返回错误信息。 2019/12/6 数据库原理
例3. 根据学生号码查询学生信息。(假设已将要查询的学生的学号赋给了主变量givensno) 查询结果为单记录的SELECT语句 例3. 根据学生号码查询学生信息。(假设已将要查询的学生的学号赋给了主变量givensno) EXEC SQL SELECT Sno, Sname, Ssex, Sage, Sdept INTO :Hsno, :Hname, :Hsex, :Hage, :Hdept FROM Student WHERE Sno = :givensno; Hsno, Hname, Hsex, Hage, Hdept和givensno均是主变量,并均已在前面的程序中说明过了。 2019/12/6 数据库原理
例4. 查询某个学生选修某门课程的成绩。(假设已将要查询的学生的学号赋给了主变量givensno,将课程号赋给了主变量givencno。) 查询结果为单记录的SELECT语句 例4. 查询某个学生选修某门课程的成绩。(假设已将要查询的学生的学号赋给了主变量givensno,将课程号赋给了主变量givencno。) EXEC SQL SELECT Sno, Cno, Grade INTO :Hsno, :Hcno, :Hgrade:Gradeid FROM SC WHERE Sno = :givensno AND Cno = :givencno; 指示变量用于指示主变量是否为空值(无成绩)。 执行此语句后,如果Gradeid小于0,则不论Hgrade为何值,均认为该学生成绩为空值。 2019/12/6 数据库原理
非CURRENT形式的UPDATE语句 非CURRENT形式的UPDATE语句 使用主变量 SET子句 WHERE子句 使用指示变量 2019/12/6 数据库原理
例5. 将全体学生1号课程的考试成绩增加若干分。 (假设增加的分数已赋给主变量Raise。) EXEC SQL UPDATE SC 非CURRENT形式的UPDATE语句 例5. 将全体学生1号课程的考试成绩增加若干分。 (假设增加的分数已赋给主变量Raise。) EXEC SQL UPDATE SC SET Grade = Grade + :Raise WHERE Cno = '1'; 2019/12/6 数据库原理
(假设该学生的学号已赋给主变量givensno, 修改后的成绩已赋给主变量newgrade。) EXEC SQL UPDATE SC 非CURRENT形式的UPDATE语句 例6. 修改某个学生1号课程的成绩。 (假设该学生的学号已赋给主变量givensno, 修改后的成绩已赋给主变量newgrade。) EXEC SQL UPDATE SC SET Grade = :newgrade WHERE Sno = :givensno; 2019/12/6 数据库原理
EXEC SQL UPDATE Student SET Sage = :Raise:Sageid WHERE Sdept = 'CS'; 非CURRENT形式的UPDATE语句 例7. 将计算机系全体学生年龄置NULL值 Sageid=-1; EXEC SQL UPDATE Student SET Sage = :Raise:Sageid WHERE Sdept = 'CS'; 等价于 SET Sage = NULL 2019/12/6 数据库原理
非CURRENT形式的DELETE语句 非CURRENT形式的DELETE语句 使用主变量 WHERE子句 2019/12/6 数据库原理
非CURRENT形式的DELETE语句 例8. 某个学生退学了,现要将有关他的所有选课记录删除掉。(假设该学生的姓名已赋给主变量stdname) EXEC SQL DELETE FROM SC WHERE Sno = (SELECT Sno FROM Student WHERE Sname = :stdname); 等价于 WHERE :stdname = (SELECT Sname WHERE Student.Sno = SC.Sno); 2019/12/6 数据库原理
非CURRENT形式的INSERT语句 INSERT语句 使用主变量 VALUES子句 使用指示变量 2019/12/6 数据库原理
例9. 某个学生新选修了某门课程,将有关记录插入SC表。(假设学生的学号已赋给主变量stdno,课程号已赋给主变量couno。) INSERT语句 例9. 某个学生新选修了某门课程,将有关记录插入SC表。(假设学生的学号已赋给主变量stdno,课程号已赋给主变量couno。) gradeid=-1; EXEC SQL INSERT INTO SC(Sno, Cno, Grade) VALUES(:stdno, :couno, :gr:gradeid); 由于该学生刚选修课程,尚未考试,因此成绩列为空。所以本例中用指示变量指示相应的主变量为空值。 2019/12/6 数据库原理
必须使用游标的SQL语句 3.7.4 使用游标的SQL语句 查询结果为多条记录的SELECT语句 CURRENT形式的UPDATE语句 CURRENT形式的DELETE语句 2019/12/6 数据库原理
查询结果为多条记录的SELECT语句 使用游标的步骤 说明游标 打开游标 推进游标指针并取当前记录 关闭游标 2019/12/6 数据库原理
EXEC SQL DECLARE <游标名> CURSOR FOR <SELECT语句>; 功能 说明游标 使用DECLARE语句 语句格式 EXEC SQL DECLARE <游标名> CURSOR FOR <SELECT语句>; 功能 是一条说明性语句,这时DBMS并不执行SELECT指定的查询操作。 2019/12/6 数据库原理
EXEC SQL OPEN <游标名>; 功能 打开游标 使用OPEN语句 语句格式 EXEC SQL OPEN <游标名>; 功能 打开游标实际上是执行相应的SELECT语句,把所有满足查询条件的记录从指定表取到缓冲区中。 这时游标处于活动状态,指针指向查询结果集中第一条记录。 2019/12/6 数据库原理
EXEC SQL FETCH [<NEXT|PRIOR|FIRST|LAST> FROM] <游标名> 推进游标指针并取当前记录 使用FETCH语句 语句格式 EXEC SQL FETCH [<NEXT|PRIOR|FIRST|LAST> FROM] <游标名> INTO <主变量>[<指示变量>] [,<主变量>[<指示变量>]]...; 2019/12/6 数据库原理
推进游标指针并取当前记录 功能 指定方向推动游标指针,然后将缓冲区中的当前记录取出来送至主变量供主语言进一步处理。 NEXT|PRIOR|FIRST|LAST:指定推动游标指针的方式。 NEXT:向前推进一条记录 PRIOR:向回退一条记录 FIRST:推向第一条记录 LAST:推向最后一条记录 缺省值为NEXT 2019/12/6 数据库原理
说明 推进游标指针并取当前记录 主变量必须与SELECT语句中的目标列表达式具有一一对应关系; FETCH语句通常用在一个循环结构中,通过循环执行FETCH语句逐条取出结果集中的行进行处理; 为进一步方便用户处理数据,现在一些关系数据库管理系统对FETCH语句做了扩充,允许用户向任意方向以任意步长移动游标指针。 2019/12/6 数据库原理
EXEC SQL CLOSE <游标名>; 功能 关闭游标,释放结果集占用的缓冲区及其他资源 说明 语句格式 EXEC SQL CLOSE <游标名>; 功能 关闭游标,释放结果集占用的缓冲区及其他资源 说明 游标被关闭后,就不再和原来的查询结果集相联系 被关闭的游标可以再次被打开,与新的查询结果相联系 2019/12/6 数据库原理
例1. 查询某个系全体学生的信息(要查询的系名由用户在程序运行过程中指定,放在主变量deptname中)。 ...... EXEC SQL INCLUDE SQLCA; EXEC SQL BEGIN DECLARE SECTION; /* 说明主变量 deptname,HSno,HSname,HSsex,HSage等*/ EXEC SQL END DECLARE SECTION; gets(deptname); /* 为主变量deptname赋值 */ EXEC SQL DECLARE SX CURSOR FOR /* 说明游标 */ SELECT Sno, Sname, Ssex, Sage FROM Student WHERE SDept=:deptname; EXEC SQL OPEN SX /* 打开游标 */ 2019/12/6 数据库原理
WHILE(1) /* 用循环结构逐条处理结果集中的记录 */ { EXEC SQL FETCH SX INTO :HSno, :HSname, :HSsex, :HSage; /* 将游标指针向前推进一行,然后从结 果集中取当前行,送相应主变量*/ if (sqlca.sqlcode <> SUCCESS) break; /* 若所有查询结果均已处理完或出现 SQL语句错误,则退出循环 */ ...... /* 由主语言语句进行进一步处理 */ }; EXEC SQL CLOSE SX; /* 关闭游标 */ ...... 2019/12/6 数据库原理
例2. 查询某些系全体学生的信息。 ...... EXEC SQL INCLUDE SQLCA; EXEC SQL BEGIN DECLARE SECTION; /* 说明主变量 deptname,HSno,HSname,HSsex,HSage等*/ EXEC SQL END DECLARE SECTION; EXEC SQL DECLARE SX CURSOR FOR SELECT Sno, Sname, Ssex, Sage FROM Student WHERE SDept = :deptname; /* 说明游标 */ 2019/12/6 数据库原理
WHILE (gets(deptname)!=NULL) /* 接收主变量deptname的值 */ EXEC SQL OPEN SX /* 打开游标 */ WHILE (1) {/* 用循环结构逐条处理结果集中的记录 */ EXEC SQL FETCH SX INTO :HSno, :HSname, :HSsex, :HSage; /* 将游标指针向前推进一行,然后从结果 集中取当前行,送相应主变量*/ if (sqlca.sqlcode <> SUCCESS) break; /* 若所有查询结果均已处理完或 出现SQL语句错误,则退出循环 */ ...... /* 由主语言语句进行进一步处理 */ }; /* 内循环结束 */ EXEC SQL CLOSE SX; /* 关闭游标 */ }; /* 外循环结束 */ ...... 2019/12/6 数据库原理
使用游标的步骤 CURRENT形式的UPDATE语句和DELETE语句 用DECLARE语句说明游标; 用OPEN语句打开游标,把所有满足查询条件的记录从指定表取到缓冲区; 用FETCH推进游标指针,并把当前记录从缓冲区中取出来送至主变量; 检查该记录是否是要修改或删除的记录,如果是则进行记录的修改或删除; 关闭游标,释放结果集占用的缓冲区或其他资源。 当SELECT语句带有UNION或ORDER BY子句时,或者SELECT语句相当于定义了一个不可更新的视图时,不能使用该形式的修改、删除语句。 2019/12/6 数据库原理
例3. 查询某个系全体学生的信息(要查询的系名由主变量deptname指定),然后根据用户的要求修改其中记录的年龄字段。 ...... EXEC SQL INCLUDE SQLCA; EXEC SQL BEGIN DECLARE SECTION; /* 说明主变量 deptname,HSno,HSname,HSsex,HSage,NEWAge等*/ EXEC SQL END DECLARE SECTION; gets(deptname); /* 为主变量deptname赋值 */ EXEC SQL DECLARE SX CURSOR FOR /* 说明游标 */ SELECT Sno, Sname, Ssex, Sage FROM Student WHERE SDept = :deptname; FOR UPDATE OF Sage; EXEC SQL OPEN SX /* 打开游标 */ 2019/12/6 数据库原理
WHILE(1) /* 用循环结构逐条处理结果集中的记录 */ { EXEC SQL FETCH SX INTO :HSno, :HSname, :HSsex, :HSage; /* 将游标指针向前推进一行,然后从结果集中取当前行,送相应主变量*/ if (sqlca.sqlcode <> SUCCESS) break; /* 若所有查询结果均已处理完或出现 SQL语句错误,则退出循环 */ printf(“%s,%s,%s,%d”,Sno,Sname,Ssex,Sage); /* 显示该记录 */ printf(“UPDATE AGE?”); scanf(“%c”,&yn); if(yn=‘y’ or yn=‘Y’) /*需要修改*/ scanf(“%d”,&NEWAge); /*输入新年龄*/ EXEC SQL UPDATE Student SET Sage = :NEWAge WHERE CURRENT OF SX; /*修改当前记录的年龄*/ } ...... }; EXEC SQL CLOSE SX; /* 关闭游标 */ 2019/12/6 数据库原理
WHILE(1) /* 用循环结构逐条处理结果集中的记录 */ { EXEC SQL FETCH SX INTO :HSno, :HSname, :HSsex, :HSage; /* 将游标指针向前推进一行,然后从结果集中取当前行,送相应主变量*/ if (sqlca.sqlcode <> SUCCESS) break; /* 若所有查询结果均已处理完或出现 SQL语句错误,则退出循环 */ printf(“%s,%s,%s,%d”,Sno,Sname,Ssex,Sage);/* 显示该记录 */ printf(“DELETE?”); scanf(“%c”,&yn); if(yn=‘y’ or yn=‘Y’) /*需要删除*/ EXEC SQL DELETE FROM Student WHERE CURRENT OF SX; /*删除当前记录*/ ...... }; EXEC SQL CLOSE SX; /* 关闭游标 */ 2019/12/6 数据库原理
例4. 查询某个系全体学生的信息(要查询的系名由主变量deptname指定),然后根据用户的要求删除其中某些记录。 ...... EXEC SQL INCLUDE SQLCA; EXEC SQL BEGIN DECLARE SECTION; /* 说明主变量 deptname, HSno, HSname, HSsex, HSage等*/ EXEC SQL END DECLARE SECTION; gets(deptname); /* 为主变量deptname赋值 */ EXEC SQL DECLARE SX CURSOR FOR /* 说明游标 */ SELECT Sno, Sname, Ssex, Sage FROM Student WHERE SDept = :deptname; EXEC SQL OPEN SX /* 打开游标 */ 2019/12/6 数据库原理
用户可以在程序运行过程中根据实际需要输入WHERE子句或HAVING子句中某些变量的值。 3.7.5 动态SQL简介 静态SQL特点 用户可以在程序运行过程中根据实际需要输入WHERE子句或HAVING子句中某些变量的值。 语句中主变量的个数与数据类型在预编译时都是确定的,只有是主变量的值是程序运行过程中动态输入的。 2019/12/6 数据库原理
动态SQL方法允许在程序运行过程中临时“组装”SQL语句。 应用范围 在预编译时下列信息不能确定时 SQL语句正文 主变量个数 主变量的数据类型 SQL语句中引用的数据库对象(列、索引、基本表、 视图等) 2019/12/6 数据库原理
动态 SQL 动态SQL的形式 语句可变 临时构造完整的SQL语句 条件可变 WHERE子句中的条件 HAVING短语中的条件 数据库对象、查询条件均可变 SELECT子句中的列名 FROM子句中的表名或视图名 2019/12/6 数据库原理
使用动态SQL技术更多的是涉及程序设计方面的 知识,而不是SQL语言本身 EXECUTE IMMEDIATE PREPARE EXECUTE DESCRIBE 使用动态SQL技术更多的是涉及程序设计方面的 知识,而不是SQL语言本身 2019/12/6 数据库原理
小 结 SQL概述 数据定义 查询 数据更新 视图 数据控制 嵌入式SQL 2019/12/6 数据库原理