å¨çº¿è§ç
å¨çº¿è§ç
å¨çº¿è§ç
Create successful ePaper yourself
Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.
第 5 章<br />
关 系 数 据 库 标 准 语 言 SQL<br />
5.1 SQL 概 述<br />
特 点 :<br />
集 DDL、DML、DCL 于 一 体<br />
非 过 程 化<br />
集 合 操 作<br />
易 学 易 用<br />
与 三 级 模 式 关 系<br />
1
5.2 查 询<br />
所 用 数 据 库 :<br />
1) 学 生 - 课 程 数 据 库<br />
Students(Sno, Sname, Ssex, Sage, Sdept)<br />
Courses(Cno, Cname, Cpno, Ccredit)<br />
SC(Sno, Cno, Grade)<br />
2
2) 电 影 数 据 库<br />
Movies(title,year,length,genre,studioName,producerC#)<br />
StarsIn(movieTitle,movieYear,starName)<br />
MovieStars(name,address,gender,birthdate)<br />
MovieExecs(name,address,cert#,netWorth)<br />
Studios(name,address,presC#)<br />
3
5.2.1 单 表 查 询<br />
* 选 择 若 干 列 --------SQL 投 影<br />
例 : 查 找 学 生 的 学 号 和 姓 名<br />
SELECT Sno, Sname<br />
FROM Students<br />
例 : 查 找 学 生 的 姓 名 、 学 号 和 所 在 系<br />
SELECT Sname, Sno, Sdept<br />
FROM Students<br />
4
例 : 查 找 学 生 的 相 关 信 息<br />
SELECT *<br />
FROM Students<br />
例 : 查 找 学 生 的 姓 名 和 出 生 年 份<br />
SELECT Sname, 2010- Sage<br />
FROM Students<br />
5
去 掉 重 复 元 组<br />
例 : 查 找 选 课 学 生 的 学 号<br />
SELECT Sno 等 价 于 SELECT ALL Sno<br />
FROM SC<br />
FROM SC<br />
SELECT DISTINCT Sno<br />
FROM<br />
SC<br />
6
* 查 询 满 足 条 件 的 元 组 ----------SQL 选 择 WHERE 子 句<br />
运 算 符 / 关 键 字<br />
比 较 =, >, =, , !<<br />
确 定 范 围 [NOT] BETWEEN ... AND ...<br />
确 定 集 合 [NOT] IN<br />
字 符 匹 配 [NOT] LIKE<br />
空 值 IS [NOT] NULL<br />
逻 辑 AND OR NOT<br />
串 的 拼 接 || P146 + SQL Server 2000 以 上<br />
7
例 : 查 找 计 算 机 系 学 生 的 名 字<br />
SELECT Sname<br />
FROM<br />
Students<br />
WHERE Sdept=‘ 计 算 机 ’<br />
8
例 : 查 找 年 龄 小 于 19 的 学 生 的 姓 名 和 年 龄<br />
SELECT Sname, Sage<br />
FROM Students<br />
WHERE Sage=19<br />
9
例 : 查 找 有 过 不 及 格 成 绩 的 学 生 的 学 号<br />
SELECT DISTINCT Sno<br />
FROM<br />
SC<br />
WHERE Grade
P144<br />
例 6.1:<br />
查 找 Disney 公 司 , 在 1990 年 制 作 的 所 有 电 影 的 有 关 信 息<br />
SELECT *<br />
FROM Movies<br />
WHERE studioName=‘Disney’ AND year=1990<br />
11
例 : 查 找 年 龄 在 20 到 23 之 间 的 学 生 的 姓 名 , 所 在 系 和 年 龄<br />
SELECT Sname, Sdept, Sage<br />
FROM Students<br />
WHERE Sage BETWEEN 20 AND 23<br />
例 : 查 找 年 龄 不 在 20 到 23 之 间 的 学 生 的 姓 名 , 所 在 系 和 年 龄<br />
SELECT Sname, Sdept, Sage<br />
FROM Students<br />
WHERE Sage NOT BETWEEN 20 AND 23<br />
12
例 : 查 找 计 算 机 系 、 经 管 系 的 学 生 的 姓 名 和 性 别<br />
SELECT Sname, Ssex<br />
FROM Students<br />
WHERE Sdept IN (‘ 计 算 机 ’,’ 经 管 ’)<br />
不 用 IN?<br />
例 : 查 找 非 计 算 机 系 非 经 管 系 的 学 生 的 姓 名 和 性 别<br />
SELECT Sname, Ssex<br />
FROM Students<br />
WHERE Sdept NOT IN (‘ 计 算 机 ’,’ 经 管 ’)<br />
不 用 IN?<br />
13
字 符 匹 配<br />
[NOT] LIKE 匹 配 串 [ ESCAPE 换 码 字 符 ]<br />
通 配 符 :<br />
% 任 意 长 度 为 n 的 字 符 串 n>=0<br />
_( 下 划 线 ) 任 意 字 符<br />
[ ] 指 定 范 围 内 的 任 意 单 个 字 符<br />
[ ^] 不 在 指 定 范 围 内 的 任 意 单 个 字 符<br />
14
例 :<br />
LIKE ‘%been%’<br />
LIKE ‘Ma%’<br />
LIKE ‘[CK]%’<br />
第 1 个 是 C 或 K<br />
LIKE ‘[^A-D]%’ 第 1 个 不 是 A-D 之 间<br />
LIKE ‘%ea_’<br />
LIKE ‘_en’<br />
15
P148 换 码 字 符 / 转 义 字 符<br />
LIKE ‘X% % X%’ ESCAPE ‘X’<br />
%……%<br />
16
P148<br />
例 6.7 查 找 电 影 名 以 ‘Star’ 开 头 后 面 紧 跟 4 个 字 母 的 所 有<br />
电 影 名<br />
SELECT title<br />
FROM<br />
Movies<br />
WHERE title LIKE ‘Star _ _ _ _’<br />
17
例 : 查 找 没 有 成 绩 的 选 课 记 录 中 的 学 号 和 课 程 号<br />
SELECT Sno,Cno<br />
FROM SC<br />
WHERE Grade IS NULL<br />
例 : 查 找 已 有 成 绩 的 选 课 记 录 中 的 学 号 和 课 程 号<br />
SELECT Sno, Cno<br />
FROM SC<br />
WHERE Grade IS NOT NULL<br />
18
例 : 查 找 计 算 机 系 年 龄 小 于 19 的 学 生 的 名 字<br />
SELECT Sname<br />
FROM Students<br />
WHERE Sdept=‘ 计 算 机 ’ AND Sage
例 : 查 找 计 算 机 系 , 经 管 系 或 建 筑 系 的 学 生 的 名 字 和 性 别<br />
SELECT Sname, Ssex<br />
FROM Students<br />
WHERE Sdept=‘ 计 算 机 ’<br />
OR Sdept=‘ 经 管 ’<br />
OR Sdept=‘ 建 筑 ’<br />
20
P145<br />
例 6.2 查 找 Disney 公 司 1990 年 拍 摄 的 影 片 的 片 名 和 长 度<br />
SELECT title,length<br />
FROM Movies<br />
WHERE studioName=‘Disney’<br />
AND year=‘1990’<br />
21
例 6.3 同 6.2 片 名 的 列 标 题 改 为 name<br />
片 长 的 列 标 题 改 为 duration<br />
SELECT title AS name,length AS duration<br />
FROM Movies<br />
WHERE studioName=‘Disney’<br />
AND year=‘1990’<br />
SQL Server 2000: 列 名 AS 别 名<br />
列 名 别 名<br />
别 名 = 列 名<br />
22
例 6.4 进 一 步 , 片 长 以 小 时 计 , 列 标 题 为 lengthInHours<br />
SELECT title AS name,<br />
length *0.016667 AS lengthInHours<br />
FROM Movies<br />
WHERE studioName=‘Disney’ AND year=‘1990’<br />
23
P145<br />
例 6.5 进 一 步 改 , 片 长 以 小 时 计 , 且 在 每 一 个 片 长 后 加<br />
‘hrs.’----- 加 一 个 新 的 列 , 每 行 都 是 ‘hrs.’<br />
SELECT title ,length *0.016667 AS length,<br />
‘hrs.’ AS inHours<br />
FROM Movies<br />
WHERE studioName=‘Disney’ AND year=1990<br />
24
P147<br />
例 : 查 找 MGM 公 司 拍 摄 的 :<br />
1970 年 以 后 或 片 长 小 于 90 分 钟 的 所 有 电 影 的 名 字<br />
SELECT title<br />
FROM Movies<br />
WHERE (year>1970 OR length
日 期 时 间 的 比 较 :<br />
第 一 个 日 期 早 于 第 二 个 小 于 (
P151<br />
例 6.11 查 询 Disney 公 司 1990 年 拍 摄 的 影 片 信 息 , 以 片 长 的<br />
升 序 排 列 , 同 样 片 长 的 , 以 片 名 的 字 母 序 排 列 。<br />
SELECT *<br />
FROM Movies<br />
WHERE studioName=‘Disney’ AND year=1990<br />
ORDER BY length,title<br />
ORDER BY 3,1<br />
27
例 : 查 找 选 修 3 号 课 程 的 学 生 的 学 号 及 相 应 成 绩 ,<br />
降 序 排 列<br />
以 成 绩<br />
SELECT Sno, Grade<br />
FROM SC<br />
WHERE Cno=‘3’<br />
ORDER BY Grade DESC<br />
28
例 : 查 找 学 生 信 息 以 所 在 系 的 升 序 , 年 龄 降 序 排 列<br />
SELECT * FROM Students<br />
ORDER BY Sdept, Sage DESC<br />
Sdept 升 序<br />
29
5.2.2 多 表 查 询<br />
* 多 表 查 询 的 方 法 之 一 :<br />
连 接 查 询 -----FROM 子 句 列 出 多 个 关 系<br />
连 接 条 件 的 一 般 格 式 :<br />
关 系 名 1. 属 性 名 1 比 较 运 算 符 关 系 名 2. 属 性 名 2<br />
比 较 运 算 符 =,>,=,
P153 例 6.12 查 找 影 片 “Star Wars” 的 制 片 人 的 姓 名<br />
Movies(title,year,length,genre,studioName,producerC#)<br />
MovieExecs(name,address,cert#,netWorth)<br />
SELECT name<br />
FROM Movies, MovieExecs<br />
WHERE title =‘Star Wars’AND producerC# = cert#<br />
31
P153<br />
例 6.13 找 所 有 具 有 相 同 地 址 的 影 星 和 高 级 主 管 的 组 合<br />
MovieStars(name,address,gender,birthdate)<br />
MovieExecs(name,address,cert#,netWorth)<br />
SELECT MovieStars.name, MovieExecs.name<br />
FROM MovieStars, MovieExecs<br />
WHERE MovieStars.address = MovieExecs.address<br />
消 除 属 性 的 二 义 性 表 名 做 前 缀<br />
32
例 : 查 询 每 个 学 生 及 其 选 课 情 况<br />
SELECT Students.*, SC.*<br />
等 值 连 接<br />
FROM Students, SC<br />
WHERE Students.Sno =SC.Sno<br />
笛 卡 尔 积 :<br />
SELECT Students.*, SC.*<br />
FROM Students, SC<br />
33
例 : 查 询 每 个 学 生 及 其 选 课 情 况<br />
SELECT Students.*, SC.Cno, SC.Grade<br />
FROM Students, SC<br />
WHERE Students.Sno =SC.Sno<br />
自 然 连 接<br />
34
例 : 查 询 每 门 课 的 课 程 号 及 其 先 修 课 的 先 修 课 的 课 程 号<br />
SELECT FIRST.Cno , SECOND.Cpno<br />
别 名<br />
FROM Courses FIRST, Courses SECOND<br />
WHERE FIRST .Cpno= SECOND .Cno<br />
自 连 接<br />
35
例 : 查 询 选 修 2 号 课 程 且 成 绩 在 90 分 以 上 的 学 生 的<br />
学 号 与 姓 名<br />
SELECT Students.Sno, Sname<br />
FROM Students, SC<br />
WHERE Students.Sno = SC.Sno<br />
AND Cno=‘2’ AND Grade>90<br />
36
例 : 查 询 每 个 学 生 选 修 的 课 程 名 及 其 成 绩 ,<br />
同 时 输 出 学 号 、 姓 名<br />
SELECT Students.Sno, Sname, Cname, Grade<br />
FROM Students, SC,Courses<br />
WHERE Students.Sno =SC.Sno<br />
AND<br />
SC.Cno=Courses.Cno<br />
37
例 : 查 询 计 算 机 系 每 个 学 生 选 修 的 课 程 名 及 其 成 绩<br />
SELECT Students.Sno, Sname, Cname, Grade<br />
FROM Students, SC,Courses<br />
WHERE Students.Sno =SC.Sno<br />
AND SC.Cno=Courses.Cno<br />
AND Sdept=‘ 计 算 机 ’<br />
38
5.2.3 使 用 聚 集 函 数<br />
AVG ([ALL|DISTINCT] 列 名 )<br />
COUNT ([ALL|DISTINCT] 列 名 )<br />
COUNT (*) 统 计 元 组 个 数<br />
MAX ( 列 名 )<br />
MIN( 列 名 )<br />
SUM ([ALL|DISTINCT] 列 名 )<br />
非 空<br />
DISTINCT<br />
对 不 重 复 列 统 计<br />
SQL Server2000 列 名 ----- 表 达 式<br />
39
P168<br />
例 6.29 找 出 所 有 高 级 主 管 的 平 均 净 资 产<br />
MovieExecs (name, address, cert#, netWorth)<br />
SELECT AVG(netWorth)<br />
FROM MovieExecs<br />
40
例 : 统 计 高 级 主 管 的 人 数<br />
SELECT COUNT(*)<br />
FROM MovieExecs<br />
假 定 重 名 查 找 不 同 名 字 的 个 数<br />
SELECT COUNT( DISTINCT name)<br />
FROM MovieExecs<br />
41
例 : 学 生 人 数<br />
SELECT COUNT(*)<br />
FROM Students<br />
例 : 选 课 学 生 人 数<br />
SELECT COUNT (DISTINCT Sno)<br />
FROM SC<br />
42
例 :1# 课 程 最 高 分<br />
SELECT MAX(Grade)<br />
FROM SC<br />
WHERE Cno=‘1’<br />
例 :1# 课 程 平 均 分<br />
SELECT AVG(Grade) FROM<br />
WHERE Cno=‘1’<br />
SC<br />
43
* 对 查 询 结 果 分 组<br />
使 用 聚 集 函 数 时 , 可 用 GROUP BY 子 句 对 查 询 结 果 进<br />
行 分 组 计 算 , 分 组 的 原 则 : 指 定 列 相 等 的 分 为 一 组<br />
HAVING 子 句 : 选 择 满 足 条 件 的 组<br />
44
例 : 课 程 , 选 课 人 数<br />
SELECT Cno, COUNT(Sno)<br />
FROM SC<br />
GROUP BY Cno<br />
先 分 组 再 统 计<br />
只 有 在 GROUP BY 子 句 中 出 现 的 属 性 , 才 能 以 非 聚 集 的<br />
形 式 出 现<br />
45
P169<br />
例 6.31 查 找 各 制 片 公 司 以 及 其 摄 制 电 影 的 总 长 度<br />
Movies(title,year,length,genre,studioName,producerC#)<br />
SELECT studioName, SUM(length)<br />
FROM Movies<br />
GROUP BY studioName<br />
46
P170 例 6.32 查 找 每 一 个 制 片 人 制 作 的 电 影 的 总 长 度<br />
Movies(title,year,length,genre,studioName,producerC#)<br />
MovieExecs(name,address,cert#,netWorth)<br />
SELECT name, SUM(length)<br />
FROM MovieExecs, Movies<br />
WHERE producerC# = cert#<br />
GROUP BY name<br />
47
例 6.34 查 找 1930 年 以 前 至 少 制 作 过 一 部 电 影 的 制 片 人 制 作<br />
的 所 有 电 影 的 总 长 度 。<br />
Movies(title,year,length,genre,studioName,producerC#)<br />
MovieExecs(name,address,cert#,netWorth)<br />
SELECT name, SUM(length)<br />
FROM MovieExecs, Movies<br />
WHERE producerC# = cert#<br />
GROUP BY name<br />
HAVING MIN(year)
例 : 经 管 系 , 选 3 门 以 上 课 程 的<br />
SELECT Students.Sno<br />
FROM SC,Students<br />
WHERE Sdept=‘ 经 管 ’<br />
AND Students.Sno=SC.Sno<br />
GROUP BY SC.Sno<br />
HAVING COUNT(*)>3<br />
对 每 一 组 统 计<br />
COUNT(Cno)<br />
49
SQL 查 询 中 子 句 的 顺 序<br />
SELECT<br />
FROM<br />
必 须<br />
WHERE<br />
GROUP BY<br />
HAVING<br />
ORDER BY<br />
50
5.2.4 子 查 询 ( 嵌 套 查 询 )------- 多 表 查 询 的 方 法 二<br />
子 查 询 是 在 SELECT 语 句 的 WHERE 子 句 中 嵌 套 的<br />
SELECT 语 句 。 外 层 SELECT 语 句 称 为 主 查 询 。<br />
又 分 为<br />
1 独 立 子 查 询 :<br />
子 查 询 独 立 求 值 , 其 结 果 代 入 主 查 询 。<br />
2 相 关 子 查 询 :<br />
子 查 询 对 主 查 询 可 能 选 出 的 每 一 行 均 执 行 一 次 ,<br />
不 能 独 立 求 值 。<br />
51
子 查 询 的 几 种 形 式 :<br />
1. [ NOT ] IN ( 子 查 询 )<br />
P160<br />
例 6.20<br />
查 找 Harrison Ford 主 演 的 所 有 电 影 的 制 片 人 姓 名<br />
StarsIn(movieTitle,movieYear,starName)<br />
Movies(title,year,length,genre,studioName,producerC# )<br />
MovieExecs(name,address,cert#,netWorth)<br />
52
1) SELECT name<br />
2) FROM MovieExecs<br />
3) WHERE cert# IN<br />
4) (SELECT producerC#<br />
5) FROM Movies<br />
6) WHERE (title,year) IN SQL Server 2000<br />
7) (SELECT movieTitle,movieYear<br />
8) FROM StarsIn<br />
9) WHERE starName=‘Harrison Ford’) )<br />
10)<br />
53
分 析 : 由 内 而 外<br />
7)8)9) 返 回 图 6-8<br />
4) 5) 6) 返 回 这 些 影 片 的 制 片 人 的 证 书 号<br />
1) 2) 3) 返 回 这 些 制 片 人 的 姓 名<br />
书 写 次 序 : 由 结 果 到 条 件<br />
54
不 采 用 子 查 询 :<br />
SELECT DISTINCT name<br />
FROM MovieExecs, Movies, StarsIn<br />
WHERE cert#=producerC# AND<br />
title = movieTitle AND<br />
year = movieYear AND<br />
starName = ‘Harrison Ford’<br />
55
例 : 查 询 与 刘 雪 同 系 的 学 生 学 号 、 姓 名 及 所 在 系<br />
法 1: 子 查 询<br />
别 名<br />
SELECT Sno, Sname, Sdept<br />
FROM Students s1<br />
WHERE s1.Sdept IN<br />
(SELECT Sdept<br />
FROM Students s2<br />
WHERE s2.Sname=‘ 刘 雪 ’ )<br />
此 例 别 名 可 省<br />
56
法 2: 自 连 接<br />
SELECT s1.Sno, s1.Sname, s1.Sdept<br />
FROM Students s1, Students s2<br />
WHERE s1.Sdept=s2.Sdept AND s2.Sname=‘ 刘 雪 ’<br />
S1<br />
Sno Sname … Sdept<br />
020501 李 勇 … 计 算 机<br />
020502 刘 雪 … 计 算 机<br />
020503 王 敏 … 经 管<br />
020504 张 功 … 计 算 机<br />
S2<br />
Sno Sname … Sdept<br />
020501 李 勇 … 计 算 机<br />
020502 刘 雪 … 计 算 机<br />
020503 王 敏 … 经 管<br />
020504 张 功 … 计 算 机<br />
57
例 : 查 询 选 修 了 ‘ 数 据 结 构 ’ 的 学 生 的 学 号 、 姓 名<br />
SELECT Sno,Sname<br />
FROM Students<br />
WHERE Sno IN<br />
( SELECT Sno<br />
FROM SC 过 程 不 相 关<br />
WHERE Cno IN<br />
(SELECT Cno<br />
FROM Courses<br />
WHERE Cname=‘ 数 据 结 构 ’))<br />
58
2. 比 较 运 算 符 [ ANY | ALL] ( 子 查 询 )<br />
返 回 单 值 时 可 使 用 >,=,=,,!
例 : 查 询 与 刘 雪 同 系 的 学 生 学 号 、 姓 名 及 所 在 系<br />
SELECT Sno, Sname, Sdept<br />
FROM Students<br />
WHERE Sdept = 返 回 单 值 对 比 IN<br />
(SELECT Sdept<br />
FROM Students<br />
WHERE Sname=‘ 刘 雪 ’ )<br />
60
例 : 查 询 选 修 了 ‘ 数 据 结 构 ’ 的 学 生 的 学 号 、 姓 名<br />
SELECT Sno, Sname<br />
FROM Students<br />
WHERE Sno IN 集 合<br />
( SELECT Sno<br />
FROM SC<br />
WHERE Cno = 单 值<br />
(SELECT Cno<br />
FROM Courses<br />
WHERE Cname=‘ 数 据 结 构 ’))<br />
过 程 不 相 关<br />
61
返 回 集 合 时 可 使 用 比 较 运 算 符 +ANY|ALL<br />
ANY-----( 某 一 个 , 有 一 个 ) ALL-----( 所 有 )<br />
=ANY IN<br />
ANY NOT IN<br />
> 、>=、!< ALL 比 最 大 的 大<br />
ANY 比 最 小 的 大<br />
P161 例 6.21 找 出 为 两 部 或 两 部 以 上 的 电 影 采 用 的 片 名<br />
SELECT DISTINCT title<br />
WHERE year < ANY<br />
(SELECT year<br />
FROM Movies<br />
FROM Movies AS Old<br />
WHERE title = Old.title )<br />
对 Old 表 中 每 一 部 电 影 , 找 有 无 同 名 而 年 代 靠 后 的<br />
对 每 一 个 Old.title 做 一 次 子 查 询<br />
A 1980<br />
B 1971<br />
相 关 子 查 询<br />
A 1973 其 他 方 法 ?<br />
C 1999<br />
B 1987<br />
63
例 : 查 询 其 他 系 比 经 管 系 某 一 学 生 年 龄 小 的 学 生 的 姓 名 、 年 龄<br />
SELECT Sname, Sage FROM Students<br />
WHERE Sage < ANY (SELECT Sage FROM Students<br />
WHERE Sdept=‘ 经 管 ’)<br />
AND Sdept’ 经 管 ’<br />
子 查 询 返 回 集 合<br />
SELECT Sname, Sage FROM Students<br />
WHERE Sage < (SELECT MAX(Sage) FROM Students<br />
WHERE Sdept=‘ 经 管 ’)<br />
AND Sdept’ 经 管 ’<br />
64
例 : 查 询 其 他 系 比 经 管 系 所 有 学 生 年 龄 都 小 的 学 生 的 姓 名 、 年 龄<br />
SELECT Sname, Sage FROM Students<br />
WHERE Sage < ALL (SELECT Sage FROM Students<br />
WHERE Sdept=‘ 经 管 ’) 返 回 集 合<br />
AND Sdept’ 经 管 ’<br />
SELECT Sname, Sage FROM Students<br />
WHERE Sage < (SELECT MIN ( Sage) FROM Students<br />
WHERE Sdept=‘ 经 管 ’)<br />
AND Sdept’ 经 管 ’<br />
65
3. 测 试 存 在 的 子 查 询<br />
EXISTS ( 子 查 询 )<br />
----- 子 查 询 结 果 集 行 数 >0 时 为 真<br />
NOT EXISTS ( 子 查 询 )<br />
---- 子 查 询 结 果 集 行 数 >0 时 为 假<br />
行 数 =0 时 为 真<br />
66
例 : 选 修 了 数 据 库 的 学 生 的 学 号 和 姓 名<br />
SELECT Sname,Sno<br />
FROM Students<br />
WHERE EXISTS<br />
(SELECT SC.*<br />
FROM SC,Courses<br />
WHERE Sno=Students.Sno<br />
AND SC.Cno=Courses.Cno<br />
AND Cname=‘ 数 据 库 ’ )<br />
相 关 子 查 询<br />
每 一 个 student 做 一 次 子 查 询<br />
67
例 : 没 有 选 修 数 据 库 的 学 生 的 学 号 和 姓 名<br />
SELECT Sname,Sno<br />
FROM Students<br />
WHERE<br />
NOT EXISTS<br />
(SELECT *<br />
FROM SC,Courses<br />
WHERE Sno=Students.Sno<br />
AND SC.Cno=Courses.Cno<br />
AND Cname=‘ 数 据 库 ’ )<br />
相 关 子 查 询<br />
68
*** 例 : 选 修 了 所 有 4 学 分 课 程 的 同 学 的 姓 名<br />
不 存 在 … 课 程<br />
没 有 选 修 记 录<br />
SELECT Sname FROM Students<br />
WHERE<br />
NOT EXISTS (SELECT Cno FROM Courses<br />
WHERE Ccredit = 4 AND<br />
NOT EXISTS<br />
(SELECT *<br />
FROM SC<br />
WHERE Sno=Students.Sno<br />
AND Cno = Courses.Cno))<br />
69
5.2.5 集 合 查 询<br />
集 合 操 作 : 并 、 交 、 差<br />
数 据 项 个 数 相 同 , 对 应 类 型 相 同 , 默 认 情 况 下 去 掉 重 复<br />
元 组 。<br />
UNION<br />
INTERSECT<br />
EXCEPT<br />
70
例 : 查 询 计 算 机 系 或 年 龄 不 大 于 19 岁 的 学 生 的 姓 名 。<br />
(SELECT Sname FROM Students<br />
WHERE Sdept=‘ 计 算 机 ’)<br />
UNION<br />
( SELECT Sname FROM Students<br />
WHERE Sage
例 : 查 询 选 修 了 课 程 1 与 课 程 2 的 学 生 学 号<br />
( SELECT Sno FROM SC<br />
WHERE Cno=‘1’)<br />
INTERSECT<br />
(SELECT Sno FROM SC<br />
WHERE Cno=‘2’)<br />
72
P157 例 6.16 查 找 身 为 高 级 主 管 , 净 资 产 在 1000 万 以 上 的 女<br />
影 星 的 姓 名 、 地 址<br />
( SELECT name,address<br />
FROM MovieStars<br />
WHERE gender = ‘F’)<br />
INTERSECT<br />
(SELECT name,address<br />
FROM MovieExecs<br />
WHERE netWorth >=10000000)<br />
73
例 6.17 查 找 不 是 高 级 主 管 的 影 星 的 姓 名 、 地 址<br />
(SELECT name,address<br />
FROM MovieStars)<br />
EXCEPT<br />
(SELECT name,address<br />
FROM MovieExecs )<br />
74
例 6.18 查 找 所 有 电 影 的 名 称 和 年 份 , 假 定 Movie 和 StarsIn<br />
中 的 影 片 不 完 全 一 样<br />
(SELECT title,year<br />
FROM Movies)<br />
UNION<br />
(SELECT movieTitle AS title ,<br />
movieYear AS year<br />
FROM StarsIn)<br />
75
5.3 数 据 库 更 新<br />
5.3.1 插 入<br />
INSERT INTO 关 系 名 [( 属 性 1, 属 性 2….)]<br />
{ VALUES ( 常 量 1, 常 量 2...) | SELECT 语 句 }<br />
说 明 : 插 入 完 整 的 行 , 可 以 省 略 属 性 名 表<br />
建 议 包 含 属 性 名 表 , 关 系 模 式 变 化 时 仍 可 正 确 插 入<br />
插 入 不 完 整 行 , 必 须 包 含 属 性 名 表<br />
没 有 列 出 的 列 填 入 NULL( 可 为 空 ) 或 缺 省 值<br />
76
P173 例 6.35<br />
INSERT INTO StarsIn(movieTitle,movieYear,starName)<br />
VALUES (‘The Maltese Falcon’,1942,’Sydney Greenstreet’)<br />
INSERT INTO StarsIn<br />
插 入 完 整 的 行 标 准 顺 序<br />
VALUES (‘The Maltese Falcon’,1942,’Sydney Greenstreet’)<br />
77
例 6.36 插 入 所 有 Movie 中 有 ,Studio 中 没 有 的 制 片 公 司<br />
INSERT INTO Studios(name)<br />
SELECT DISTINCT studioName 子 查 询<br />
FROM Movies<br />
WHERE studioName NOT IN<br />
(SELECT name<br />
FROM Studios)<br />
属 性 address, presC# 取 NULL<br />
78
5.3.2 删 除<br />
DELETE FROM 关 系 名<br />
[WHERE 条 件 ]<br />
无 WHERE 子 句 删 除 所 有 行<br />
79
例 6.37: 删 除 Sydney Greenstreet 主 演 1942 年 的 影 片<br />
‘The Maltese Falcon’ 这 一 事 实 .<br />
DELETE FROM StarsIn<br />
WHERE movieTitle = ‘The Maltese Falcon’<br />
AND<br />
AND<br />
movieYear=1942<br />
starName= ‘ Sydney Greenstreet’<br />
多 对 多 ( 年 , 片 名 )---- 影 片<br />
准 确 描 述 要 删 除 的 元 组<br />
80
例 6.38: 删 除 所 有 净 收 入 不 足 1000 万 美 金 的 高 级 主 管<br />
DELETE FROM MovieExecs<br />
WHERE netWorth < 10000000<br />
删 除 满 足 条 件 的 若 干 元 组<br />
81
5.3.3 修 改<br />
UPDATE 关 系 名<br />
SET 属 性 1= 表 达 式 1<br />
[, 属 性 2= 表 达 式 2 ……]<br />
[WHERE 条 件 ]<br />
违 反 完 整 性 约 束 更 新 不 会 发 生<br />
无 WHERE 子 句 更 新 所 有 行<br />
82
P174<br />
例 6.39 在 所 有 身 为 制 片 公 司 总 裁 的 高 级 主 管 的 名 字 前 面<br />
加 上 头 衔 “Pres.”<br />
UPDATE MovieExecs<br />
SET name =‘Pres.’|| name<br />
WHERE cert# IN<br />
( SELECT presC#<br />
FROM Studios )<br />
+ 串 合 并<br />
83
5.4 建 表 语 句<br />
5.4.1 常 用 数 据 类 型 (SQL Server2000)<br />
CHAR(n) VARCHAR(n)<br />
BIT 0/1 输 入 0 之 外 的 看 作 1<br />
INT 4 字 节 SMALLINT 2 字 节<br />
FLOAT(n) n=1-24 4 字 节 n=25-53 8 字 节<br />
REAL=float(24)<br />
DECIMAL(p[,s]) p: 十 进 制 位 数 (1-38) s: 小 数 位 数<br />
5-17 字 节<br />
DATETIME 日 期 时 间 可 省 略 其 中 之 一<br />
‘2000/10/02’<br />
84
5.4.2 表 的 建 立 与 删 除 ( 简 单 定 义 )<br />
例 :<br />
CREATE TABLE MovieStars(<br />
name CHAR(30),<br />
address VARCHAR(255),<br />
gender CHAR(1),<br />
birthdate DATETIME )<br />
85
删 除 表<br />
DROP TABLE 关 系 名<br />
86
5.4.3 更 改 关 系 模 式 ( 改 表 结 构 )<br />
ALTER TABLE 表 名 ADD 属 性 名 类 型<br />
ALTER TABLE 表 名 DROP COLUMN 属 性 名 2000<br />
例 : 为 MovieStar 表 增 加 列 :phone<br />
ALTER TABLE MovieStars ADD phone CHAR(16)<br />
删 除 MovieStar 表 中 列 :birthdate<br />
ALTER TABLE MovieStars<br />
DROP COLUMN birthdate<br />
87
5.4.4 默 认 值 ( 缺 省 值 )<br />
例 :<br />
CREATE TABLE MovieStars(<br />
name CHAR(30),<br />
address VARCHAR(255),<br />
gender CHAR(1) DEFAULT ‘?’,<br />
birthdate DATETIME<br />
DEFAULT ‘0000-00-00’ )<br />
88
例 : 新 加 的 属 性 phone<br />
若 设 置 默 认 值<br />
ALTER TABLE MovieStars<br />
ADD phone CHAR(16)<br />
DEFAULT ‘unlist’<br />
89
5.5 SQL 中 的 数 据 约 束<br />
主 动 性 元 素<br />
----- 保 存 在 数 据 库 中<br />
在 指 定 的 事 件 发 生 时<br />
执 行 的 语 句 或 判 定 的 表 达 式<br />
提 供 数 据 的 完 整 性 :<br />
实 体 完 整 性<br />
参 照 完 整 性 用 户 定 义 完 整 性<br />
90
SQL 中 完 整 性 约 束 的 几 种 方 法 :<br />
键 约 束<br />
参 照 完 整 性<br />
域 的 约 束<br />
基 于 属 性 / 元 组 的 CHECK 约 束<br />
断 言 ( 整 个 关 系 或 关 系 间 的 约 束 )<br />
触 发 器 ( 编 程 者 指 定 触 发 时 刻 一 组 命 令 )<br />
存 储 过 程<br />
91
5.5.1 SQL 中 的 键 约 束 和 单 值 约 束<br />
键 约 束 ( 主 键 约 束 ):<br />
用 PRIMARY KEY 表 示 ( 唯 一 非 空 )<br />
单 值 约 束 :<br />
用 UNIQUE 表 示 ( 唯 一 可 空 )<br />
基 本 表 中 只 能 有 一 个 主 键<br />
可 以 有 多 个 UNIQUE 说 明<br />
92
5.5.1.1 ( 主 ) 键 的 定 义 ( 说 明 )<br />
主 键 由 关 系 的 一 个 或 多 个 属 性 组 成<br />
在 建 表 时 说 明<br />
一 种 : 在 列 出 属 性 时 说 明 某 个 属 性 为 主 键<br />
另 一 种 : 加 入 额 外 的 说 明 ,<br />
说 明 某 个 或 一 组 属 性 为 主 键<br />
93
例 :<br />
CREATE TABLE MovieStars(<br />
name CHAR(30) PRIMARY KEY,<br />
address VARCHAR(255),<br />
gender CHAR(1),<br />
birthdate DATETIME )<br />
name 为 主 键<br />
出 现 在 属 性 说 明 中<br />
94
CREATE TABLE MovieStars(<br />
name CHAR(30),<br />
address VARCHAR(255),<br />
gender CHAR(1),<br />
birthdate DATETIME ,<br />
PRIMARY KEY (name) )<br />
单 独 说 明 name 为 主 键<br />
95
例 :CREATE TABLE Movies(<br />
title VARCHAR(50),<br />
year CHAR(4),<br />
….<br />
producerC# INT,<br />
PRIMARY KEY (title,year))<br />
组 合 码 做 主 键<br />
96
5.5.1.2 单 值 约 束 的 定 义 ( 说 明 )<br />
例 : 职 工 表<br />
CREATE TABLE Employees(<br />
Eno<br />
SSN<br />
CHAR(5) PRIMARY KEY,<br />
CHAR(18) UNIQUE,<br />
Name CHAR(30) ,<br />
DriverLicNo CHAR(10) UNIQUE,<br />
Gender CHAR(1),<br />
Birthdate DATETIME )<br />
97
例 :<br />
CREATE TABLE MovieStars(<br />
name CHAR(30) PRIMARY KEY,<br />
address VARCHAR(255),<br />
gender CHAR(1),<br />
birthdate DATETIME ,<br />
UNIQUE (address))<br />
单 独 说 明<br />
98
PRIMARY KEY 与 UNIQUE 细 微 差 别 :<br />
1. 外 键 只 能 参 照 某 个 关 系 的 主 键<br />
2.DBMS 的 实 现 常 常 :<br />
为 主 键 建 索 引<br />
按 主 键 排 序<br />
99
5.5.1.3 实 施 键 约 束 强 制 键 约 束<br />
通 常 的 方 法 : 主 键 上 建 唯 一 性 索 引<br />
好 处 :<br />
1) 查 询 条 件 含 主 键 时 , 只 需 查 看 索 引<br />
不 必 查 看 关 系 中 的 所 有 元 组<br />
2) 在 插 入 、 修 改 时 检 验 键 约 束 , 只 需<br />
查 看 索 引 表 速 度 快<br />
违 背 约 束 则 禁 止 更 新<br />
100
5.5.2 SQL 中 的 参 照 完 整 性 约 束 与 外 键<br />
外 键 :<br />
若 关 系 R 的 一 个 属 性 ( 或 属 性 组 ) X, 不 是 R 的<br />
主 键 , 而 是 (/ 对 应 ) 另 一 个 关 系 S 的 主 键 , 则 称 X 为<br />
关 系 R 的 外 键 ;<br />
称 R 为 参 照 关 系 、 称 S 为 被 参 照 关 系 。<br />
Employees(Eno,Ename,Eage,Dno)<br />
Departments(Dno,Dname,Phone)<br />
参 照 关 系<br />
被 参 照 关 系<br />
101
参 照 完 整 性 :<br />
非 空 的 外 键 在 S 中 存 在 且 唯 一<br />
职 工 的 部 门 号 对 应 的 是 存 在 的 部 门<br />
102
5.5.2.1 定 义 外 键 约 束<br />
建 表 时<br />
一 种 : 单 一 属 性 作 外 键 在 属 性 定 义 后 加<br />
REFERENCES 被 参 照 表 名 ( 属 性 )<br />
另 一 种 : 单 独 说 明 一 个 或 多 个 属 性 为 外 键<br />
FOREIGN KEY 属 性 组<br />
REFERENCES 被 参 照 表 名 ( 属 性 组 )<br />
103
例 : 考 虑 MovieExecs 表 和 Studios 表<br />
Studios(name,address,presC# ) 外 键<br />
参 照 关 系<br />
MovieExecs(name,address,cert#,netWorth)<br />
被 参 照 关 系<br />
一 个 高 级 主 管 记 录 可 对 应 多 个 制 片 公 司 ( 多 个 公 司 的 总 裁 )<br />
父 表 / 主 表<br />
子 表 / 明 细 表<br />
104
CREATE TABLE Studios(<br />
name CHAR(30) PRIMARY KEY,<br />
address VARCHAR (255),<br />
presC#<br />
INT REFERENCES<br />
MovieExecs(cert#))<br />
在 属 性 定 义 中 说 明 外 键<br />
105
CREATE TABLE Studios(<br />
name CHAR(30) PRIMARY KEY,<br />
address VARCHAR (255),<br />
presC# INT ,<br />
FOREIGN KEY presC#<br />
REFERENCES MovieExecs(cert#))<br />
单 独 说 明 外 键<br />
106
外 键 为 组 合 码 时 , 必 须 单 独 说 明<br />
例 :Softwares(name,version,maker)<br />
Use(name,version,year,money)<br />
CREATE TABLE Use(<br />
name … , version … , …,money … ,<br />
PRIMARY KEY (name,version,year),<br />
FOREIGN KEY (name,version)<br />
REFERENCES Softwares(name,version))<br />
107
5.5.2.2 保 持 参 照 完 整 性<br />
非 空 的 外 键 存 在 于 被 参 照 关 系 中<br />
考 虑 :<br />
Students(Sno,Sname,Sage)<br />
SC(Sno,Cno,Grade)<br />
Sno Cno 两 个 外 键<br />
Courses(Cno,Cname,Ccredit)<br />
Eoyees(Eno,Ename,Eage,Dno)<br />
Dno 外 键<br />
Departments(Dno,Dname,Phonempl)<br />
108
方 案 1: 默 认 策 略 ---- 拒 绝 非 法 更 新<br />
a. 插 子 记 录 必 须 有 对 应 的 主 记 录<br />
如 果 插 入 选 课 记 录 (020506,25,90)<br />
课 程 表 中 没 有 25 号 课 程<br />
则 禁 止 插 入<br />
109
. 改 子 记 录 必 须 有 对 应 的 主 记 录<br />
如 果 选 课 记 录 改 为 (020506,25,90)<br />
课 程 表 中 没 有 25 号 课 程<br />
则 禁 止 修 改<br />
110
c. 有 子 记 录 时 禁 止 删 除 主 记 录<br />
有 020506 的 选 课 记 录 时 ,<br />
不 许 删 除 Student 中 020506 的 记 录<br />
d. 有 子 记 录 时 禁 止 修 改 主 记 录<br />
有 020506 的 选 课 记 录<br />
欲 将 Student 表 中 的 020506 改 为 030712<br />
则 禁 止 修 改<br />
111
方 案 2: 级 联 策 略<br />
在 删 除 和 更 新 主 表 时 对 子 表 进 行 级 联 处 理 .<br />
a. 删 除 主 记 录 同 时 删 除 子 记 录<br />
删 除 Students 中 020506 的 记 录<br />
同 时 删 除 020506 的 所 有 选 课 记 录<br />
112
. 更 新 主 记 录 同 时 更 新 子 记 录<br />
更 新 Students 中 020506 的 学 号 为 030712<br />
同 时 更 新 020506 的 所 有 选 课 记 录 的<br />
学 号 为 030712<br />
113
方 案 3: 置 空 策 略<br />
在 删 除 和 更 新 主 表 时 对 子 表 进 行 置 空 处 理 .<br />
a. 删 除 主 记 录 同 时 将 子 记 录 外 键 改 为 NULL<br />
删 除 部 门 表 中 4 号 部 门 信 息<br />
同 时 将 4 号 部 门 的 20 个 职 工 记 录 的 部 门 号 置 空<br />
114
. 更 新 主 记 录 同 时 将 子 记 录 外 键 改 为 NULL<br />
修 改 部 门 表 中 4 号 部 号 为 14 号<br />
同 时 将 4 号 部 门 的 20 个 职 工 记 录 的 部 门 号 置 空<br />
115
这 些 策 略 是 与 外 键 一 起 说 明 的 , 可 以 单 独 用 于 删<br />
或 更 新<br />
例 :<br />
CREATE TABLE Studios(<br />
name CHAR(30) PRIMARY KEY,<br />
address VARCHAR(255),<br />
presC# INT<br />
REFERENCES MovieExecs (cert#)<br />
ON DELETE SET NULL<br />
ON UPDATE CASCADE)<br />
116
5.5.3 SQL 中 对 属 性 值 的 约 束<br />
5.5.3.1 非 空 约 束<br />
属 性 后 加 NOT NULL<br />
例 :<br />
CREATE TABLE Studios(<br />
name CHAR(30) PRIMARY KEY,<br />
address VARCHAR (255) NOT NULL,<br />
presC# INT REFERENCES<br />
MovieExecs(cert#) NOT NULL)<br />
117
5.5.3.2 基 于 属 性 的 CHECK 约 束<br />
建 表 时 属 性 后 CHECK( 条 件 )<br />
属 性 值 改 变 时 进 行 检 验 不 合 格 拒 绝 更 新<br />
原 则 上 可 以 使 用 WHERE 中 条 件<br />
含 子 查 询 时 可 能 有 问 题 见 下 例<br />
118
例<br />
用 CHECK 取 代 外 键 约 束 的 错 误 尝 试<br />
CREATE TABLE Studios(<br />
name CHAR(30) PRIMARY KEY,<br />
address VARCHAR (255),<br />
presC# INT CHECK ( presC# IN<br />
(SELECT cert# FROM MovieExecs) )<br />
插 入 、 更 新 Studios 时<br />
系 统 进 行 检 验 阻 止 不 合 理 的 数 据 进 入<br />
但 , 删 除 MovieExecs 中 元 组 时 , 不 做 此 校 验 , 可 能 使<br />
Studio 表 中 出 现 若 干 元 组 , 找 不 到 相 应 的 cert#<br />
119
例<br />
CREATE TABLE Studios(<br />
name CHAR(30) PRIMARY KEY,<br />
address VARCHAR (255),<br />
presC# INT<br />
REFERENCES MovieExecs(cert#)<br />
CHECK (presC#>=100000))<br />
6 位 编 号<br />
120
CREATE TABLE MovieStars(<br />
name CHAR(30) PRIMARY KEY,<br />
address VARCHAR(255) ,<br />
gender CHAR(1)<br />
CHECK (gender IN (‘F’,’M’) ) ,<br />
birthdate DATETIME )<br />
121
**5.5.3.3 基 于 元 组 的 CHECK 约 束<br />
涉 及 整 个 元 组 而 不 仅 针 对 某 一 个 属 性<br />
原 则 上 同 WHERE 条 件<br />
有 子 查 询 时 小 心<br />
例 男 影 星 姓 名 前 不 能 加 ‘Ms.’<br />
CREATE TABLE MovieStars(<br />
name CHAR(30) PRIMARY KEY,<br />
address VARCHAR(255) ,<br />
gender CHAR(1) CHECK (gender IN (‘F’,’M’) ) ,<br />
birthdate DATETIME<br />
CHECK (gender=‘F’ OR name NOT LIKE ‘Ms.%’)<br />
122
**5.5.3.4 域 约 束<br />
定 义 域 时 定 义 约 束<br />
CREATE DOMAIN GenderDomain CHAR(1)<br />
CHECK (VALUE IN (‘F’,’M’))<br />
CREATE TABLE MovieStars(<br />
name CHAR(30) PRIMARY KEY,<br />
address VARCHAR(255) UNIQUE,<br />
gender<br />
GenderDomain,<br />
birthdate DATETIME )<br />
123
**5.5.4 约 束 的 更 新<br />
约 束 命 名<br />
更 改 表 的 约 束<br />
删 除 添 加<br />
更 改 域 的 约 束<br />
更 改 断 言<br />
124
5.5.5 触 发 器 及 其 他<br />
触 发 器 : 指 定 触 发 事 件 触 发 一 连 串 操 作<br />
例 : 阻 止 降 低 高 级 主 管 净 资 产 的 操 作 ( 改 回 旧 值 )<br />
125
CREATE TRIGGER NetWorthTrigger<br />
AFTER UPDATE OF netWorth ON MovieExecs<br />
REFERRENCING<br />
OLD ROW AS OldTuple,<br />
NEW ROW AS NewTuple<br />
FOR EACH ROW<br />
WHEN<br />
(OldTuple.netWorth>NewTuple.netWorth)<br />
UPDATE MovieExecs<br />
SET netWorth=OldTuple.netWorth<br />
WHERE cert#=NewTuple.cert#<br />
126
断 言 : 约 束 涉 及 整 个 关 系<br />
甚 至 其 他 关 系<br />
CREATE ASSERTION……<br />
制 片 公 司 制 作 的 所 有 电 影 总 长 >10000 分 钟<br />
不 存 在 净 资 产 不 足 1000 万 美 金 的 总 裁<br />
127
5.6 索 引<br />
# 索 引 的 意 义<br />
SELECT *<br />
FROM Movies<br />
WHERE year=1990 AND studioName=‘Disney’<br />
Movies 10 000 个 元 组<br />
200 个 1990 年 制 作<br />
可 否 只 从 200 个 1990 年 制 作 的 影 片 中 查 询 ‘Disney’ 公 司<br />
的 影 片 ?<br />
以 年 代 建 索 引<br />
加 快 查 询 速 度<br />
128
索 引 的 分 类 :<br />
UNIQUE( 唯 一 性 ):<br />
任 意 两 行 的 被 索 引 列 , 不 能 出 现 重 复 值 ( 包 括 空 值 )<br />
CLUSTERED( 簇 式 ):<br />
行 的 物 理 顺 序 和 索 引 顺 序 相 同<br />
更 新 时 移 动 数 据<br />
NONCLUSTERED( 非 簇 式 ):<br />
一 表 仅 一 个<br />
默 认<br />
包 含 索 引 值 和 指 向 数 据 行 的 指 针 不 要 求 行 的 物 理 顺 序<br />
和 索 引 顺 序 相 同 一 表 可 多 个<br />
复 合 索 引 : 对 表 的 两 列 或 多 列 进 行 索 引<br />
129
例 : 在 单 一 属 性 上 建 索 引<br />
CREATE INDEX YearIndex ON Movies (year)<br />
索 引 名<br />
关 系 名 属 性<br />
例 : 在 一 组 属 性 上 建 索 引<br />
CREATE INDEX KeyIndex ON Movies (title,year)<br />
索 引 名<br />
关 系 名 属 性 组<br />
130
删 除 索 引 :<br />
DROP INDEX YearIndex<br />
索 引 名<br />
131
关 于 速 度 与 开 销<br />
索 引 的 有 利 之 处 :<br />
提 高 该 属 性 值 已 知 的 查 询 的 速 度<br />
索 引 的 不 利 之 处 :<br />
占 空 间 增 删 改 时 维 护 索 引 增 加 系 统 开 销<br />
132
Movies 在 什 么 列 建 索 引 ?<br />
year title (year,title)<br />
速 度 慢 / 空 间 小 适 中 速 度 快 / 空 间 大<br />
维 护 的 开 销 小<br />
维 护 的 开 销 大<br />
考 虑 :<br />
表 更 新 多 ? 查 询 多 ?<br />
经 常 用 什 么 列 查 询 ?<br />
133
5.7 视 图<br />
为 什 么 要 有 视 图 ?<br />
视 图 是 从 一 个 或 几 个 基 本 表 ( 视 图 ) 导 出 的 表 。<br />
134
从 视 图 中 ( 看 到 ) 的 数 据 是<br />
由 定 义 视 图 的 SELECT 语 句 查 询 而 来 。<br />
与 基 本 表 不 同 , 系 统 只 保 存 视 图 的 定 义 , 不 重<br />
复 保 存 其 中 数 据 。<br />
135
视 图 的 使 用 :<br />
可 以 对 视 图 进 行 查 询 , 就 象 它 实 际 存 在 一 样<br />
------ 查 询 到 的 数 据 来 自 基 本 表<br />
某 些 情 况 下 , 甚 至 可 以 对 视 图 进 行 更 新<br />
------- 更 新 基 本 表 中 的 数 据<br />
136
视 图 的 好 处 :<br />
1. 一 定 程 度 的 数 据 的 逻 辑 独 立 性 ( 更 新 受 限 )<br />
2. 安 全 性<br />
3. 简 化 用 户 的 数 据 处 理<br />
4. 从 需 要 的 角 度 看 待 数 据<br />
137
5.7.1 视 图 的 定 义<br />
句 法 :<br />
CREATE VIEW 视 图 名 [( 列 名 表 )]<br />
AS<br />
SELECT 语 句<br />
138
说 明 :<br />
1. 可 建 视 图 的 视 图 (SELECT 中 象 使 用 基 本 表<br />
一 样 使 用 视 图 )<br />
2. 可 用 列 名 表 指 出 所 有 列 名 或 省 去 列 名 表<br />
不 指 定 视 图 的 列 名<br />
—— 使 用 查 询 结 果 表 列 名<br />
如 下 情 况 必 须 指 定 列 名 :<br />
1 希 望 使 用 不 同 的 列 名<br />
2 表 达 式 、 函 数 所 得 的 列<br />
3 多 表 中 的 公 共 列<br />
139
P202<br />
例 8.1 将 关 系<br />
Movies(title,year,length,genre,studioName,producerC#)<br />
的 一 部 分 , 即 Paramount( 派 拉 蒙 ) 制 片 公 司 制 作 的 电 影 名<br />
称 和 年 份 作 为 一 个 视 图 :<br />
CREATE VIEW ParamountMovies AS<br />
SELECT title,year FROM Movies<br />
WHERE studioName = ‘Paramount’<br />
视 图 名<br />
视 图 属 性 ( 列 ) 视 图 的 定 义<br />
140
将 视 图 的 定 义 存 入 系 统 表 , 不 执 行 SELECT 语 句 。<br />
对 视 图 查 询 时<br />
按 视 图 的 定 义 从 基 本 表 中 将 数 据 查 出 。<br />
141
例 : 建 立 数 学 系 学 生 的 视 图<br />
CREATE VIEW MA_Students<br />
AS<br />
SELECT Sno ,Sname ,Sage<br />
FROM Students<br />
WHERE Sdept=‘ 数 学 ’<br />
视 图 的 列 名 表<br />
行 列 子 集 视 图 : 取 行 列 、 保 留 码<br />
142
视 图 可 以 建 立 在 多 表 ( 视 图 ) 上<br />
P203 例 8.2: 建 立 包 含 电 影 名 和 制 片 人 名 的 视 图<br />
CREATE VIEW MovieProds<br />
AS<br />
SELECT title,name<br />
FROM Movies,MovieExecs<br />
WHERE producerC# = cert#<br />
视 图 属 性 名 :title , name<br />
143
例 : 数 学 系 选 了 1 号 课 程 的 学 生 视 图<br />
CREATE VIEW MA_S1 (Sno,Sname,Grade)<br />
AS<br />
SELECT Students.Sno, Sname, Grade<br />
FROM Students,SC<br />
WHERE Sdept=‘ 数 学 ’<br />
AND Students.Sno=SC.Sno<br />
AND SC.Cno=‘1’<br />
视 图 属 性 表 不 可 省<br />
144
P203 有 时 更 愿 意 使 用 自 己 选 择 的 属 性 名<br />
改 例 8.2: 建 立 包 含 电 影 名 和 制 片 人 名 的 视 图<br />
CREATE VIEW<br />
MovieProds(movieTitle , prodName)<br />
AS<br />
SELECT title,name<br />
FROM Movies,MovieExecs<br />
WHERE producerC# = cert#<br />
视 图 属 性 名 :movieTitle , prodName<br />
145
例 数 学 系 选 了 1 号 课 程 且 分 数 在 90 以 上<br />
的 学 生 视 图<br />
CREATE VIEW MA_S2<br />
AS<br />
SELECT Sno,Sname,Grade<br />
FROM MA_S1<br />
WHERE Grade>=90<br />
视 图 的 视 图<br />
146
例 : 定 义 一 个 反 映 学 生 出 生 年 份 的 视 图<br />
CREATE VIEW BT_S (Sno, Sname, Sbirth)<br />
AS<br />
SELECT Sno, Sname, 2010- Sage<br />
FROM Students<br />
147
例 : 将 学 生 的 学 号 和 各 科 的 平 均 成 绩 定 义<br />
为 一 个 视 图<br />
CREATE VIEW S_G ( Sno , Gavg )<br />
AS<br />
SELECT Sno, AVG(Grade)<br />
FROM SC<br />
GROUP BY Sno<br />
148
例 :<br />
CREATE VIEW<br />
F_Students(stdnum,name,sex,age,dept)<br />
AS<br />
SELECT *<br />
FROM Students<br />
WHERE Ssex=‘ 女 ’<br />
依 当 前 基 本 表 生 成 视 图 定 义 , 基 本 表 改 变 则 不<br />
能 正 常 工 作<br />
149
法 1:<br />
CREATE VIEW<br />
F_Students (stdnum,name,sex,age,dept)<br />
AS SELECT Sno,Sname,Ssex,Sage,Sdept<br />
FROM Students<br />
WHERE Ssex=‘ 女 ’<br />
法 2: 删 除 旧 视 图 , 重 建 。<br />
150
5.7.2 视 图 的 查 询 —— 像 基 本 表 一 样 使 用<br />
P203 例 8.3<br />
SELECT title<br />
FROM ParamountMovies<br />
WHERE year=1979<br />
将 视 图 看 作 “ 基 本 表 ”<br />
151
DBMS 执 行 视 图 查 询 时 ,<br />
首 先 进 行 有 效 性 检 查 , 检 查 涉 及 的 表 、 视 图 是<br />
否 存 在 ,<br />
如 存 在 从 系 统 表 中 取 出 视 图 定 义 ,<br />
把 定 义 中 的 SELECT 语 句 与 对 视 图 进 行 的 查 询 的<br />
SELECT 语 句 结 合 起 来 , 转 换 成 对 基 本 表 的 查 询 ,<br />
然 后 , 再 执 行 这 个 修 正 后 的 查 询 。<br />
152
与 上 例 等 价 的 对 基 本 表 的 查 询 :<br />
SELECT title<br />
FROM Movies<br />
WHERE studioName = ‘Paramount’<br />
AND year=1979<br />
153
例 : 查 询 数 学 系 年 龄 小 于 20 的 学 生 的 学 号<br />
和 年 龄<br />
SELECT Sno,Sage<br />
FROM MA_Students<br />
WHERE Sage
P203<br />
例 8.4 可 以 写 出 涉 及 基 本 表 和 视 图 的 查 询<br />
SELECT DISTINCT starName<br />
FROM ParamountMovies, StarsIn<br />
WHERE title=movieTitle<br />
AND year=movieYear<br />
155
例 : 使 用 视 图 MovieProds 查 询 “Gone With the<br />
Wind”( 乱 世 佳 人 )<br />
SELECT name<br />
FROM MovieProds<br />
WHERE title=‘Gone With the Wind’<br />
视 图 定 义 中 有 表 的 连 接<br />
等 价 的 查 询<br />
156
5.7.3 视 图 的 更 新<br />
将 视 图 看 作 基 本 表<br />
实 际 : 通 过 视 图 修 改 数 据<br />
修 改 的 是 基 本 表 中 的 数 据 !<br />
诸 多 限 制<br />
157
由 于 视 图 的 复 杂 性 通 过 视 图 改 数 据 有 一 定 限 制 , 各 系 统 不 同 。<br />
1. 单 表 导 出 的 行 列 子 集 视 图 。<br />
2. 视 图 由 多 表 连 接 而 来 , 数 据 取 自 多 表 ,<br />
一 次 修 改 只 能 影 响 其 中 一 张 基 本 表 。<br />
3. 不 能 在 包 含 计 算 值 、 函 数 、 聚 集 函 数 的 视 图<br />
列 上 修 改 。<br />
4. 权 限 完 整 性 约 束<br />
158
# 为 什 么 有 些 视 图 不 能 更 新<br />
MovieProds<br />
插 入 一 个 片 名 一 个 制 片 人<br />
不 知 证 书 号<br />
S_G ( Sno , Gavg )<br />
更 新 ?<br />
159
DBMS 执 行 视 图 更 新 时 ,<br />
首 先 进 行 有 效 性 检 查 , 检 查 涉 及 的 表 、 视 图 是<br />
否 存 在 ,<br />
如 存 在 从 系 统 表 中 取 出 视 图 定 义 ,<br />
把 定 义 中 的 SELECT 语 句 与 对 视 图 进 行 的 更 新 语<br />
句 结 合 起 来 , 转 换 成 对 基 本 表 的 更 新 ,<br />
然 后 , 再 执 行 这 个 修 正 后 的 更 新 。<br />
160
P205 例 8.5 向 视 图 ParamountMovies 插 入 元 组<br />
INSERT INTO ParamountMovies<br />
VALUES (‘Star Trek’,1979)<br />
CREATE VIEW ParamountMovies AS<br />
SELECT title,year FROM Movies<br />
WHERE studioName = ‘Paramount’<br />
只 影 响 一 个 基 本 表 的 若 干 行 若 干 列<br />
161
转 换 :<br />
INSERT INTO<br />
Movies(studioName,title,year)<br />
VALUES (‘Paramount’,‘Star Trek’,1979)<br />
length genre producerC# 默 认 值 /NULL<br />
162
例 :INSERT INTO MA_Students<br />
VALUES (‘020510’, ‘ 赵 新 ’, 20)<br />
转 换<br />
163
例 8.6<br />
从 可 更 新 视 图 ParamountMovies 中 删 除 所 有 名 称<br />
中 含 有 ‘Trek’ 的 电 影<br />
DELETE FROM<br />
ParamountMovies<br />
WHERE title LIKE ‘%Trek%’<br />
转 换 : DELETE FROM<br />
Movies<br />
WHERE title LIKE ‘%Trek%’<br />
AND studioName=‘Paramount’<br />
164
例 :DELETE FROM<br />
MA_Students<br />
WHERE Sno=‘950129’<br />
转 换<br />
165
例 更 新 ParamountMovies<br />
UPDATE ParamountMovies<br />
SET year=1980<br />
WHERE title= ‘Star Trek’<br />
转 换 :<br />
UPDATE Movies<br />
SET year=1980<br />
WHERE title= ‘Star Trek’<br />
AND studioName=‘Paramount’<br />
166
例 :UPDATE<br />
MA_Students<br />
SET Sname=‘ 刘 欣 ’<br />
WHERE Sno=‘020502’<br />
转 换 成 对 Students 表 的 更 新<br />
167
5.7.4 删 除 视 图<br />
DROP VIEW<br />
视 图 名 列 表<br />
例 :DROP VIEW MA_S1<br />
MA_S2 的 定 义 仍 在 系 统 表 中 ,<br />
但 不 能 使 用 。<br />
168
5.6 空 值 和 外 部 连 接<br />
5.6.1 对 空 值 的 运 算<br />
P149 空 值 : 未 知 或 不 存 在 的 值<br />
空 值 的 运 算<br />
1. NULL 与 其 他 + 得 NULL<br />
2. NULL 与 其 他 比 较 得 UNKNOWN<br />
UNKNOWN 与 TRUE FALSE 类 似<br />
另 一 种 真 值<br />
169
5.6.2 真 值 UNKNOWN<br />
P150 图 6-2<br />
例 6.10 SELECT *<br />
FROM Movies<br />
WHERE length120<br />
若 length=NULL<br />
WHERE 条 件 UNKNOWN<br />
返 回 具 有 非 空 长 度 的 Movie 元 组<br />
而 不 是 所 有 元 组<br />
170
5.6.3 SQL 的 连 接 表 达 式<br />
P163-165<br />
FROM<br />
Movies CROSS JOIN StarsIn<br />
SELECT title,year,genre,studioName,<br />
producerC#,starName<br />
FROM<br />
Movies JOIN StarsIn ON<br />
title=movieTitle AND year=movieYear<br />
171
5.6.4 自 然 连 接<br />
P164<br />
FROM MovieStars<br />
NATURAL JOIN MovieExecs<br />
172
5.6.5 外 部 连 接<br />
P164<br />
NATURAL FULL OUTER JOIN<br />
NATURAL LEFT OUTER JOIN<br />
NARUAL RIGHT OUTER JOIN<br />
173
掌 握 : 视 图 定 义 和 查 询 , 视 图 优 点 。<br />
熟 练 掌 握 : SQL 特 点 。 基 本 表 、 查 询 表 和 视 图 表<br />
的 特 点 和 区 别 ;SQL 中 的 数 据 类 型 ; 表 创 建 、<br />
修 改 和 删 除 ; 索 引 的 创 建 和 删 除 ;SQL 查 询 语<br />
句 结 构 ; 空 值 概 念 ; 聚 集 函 数 (sum, count,<br />
avg, max, min); 连 接 查 询 ( 略 去 外 连 接 );<br />
嵌 套 查 询 ; 集 合 查 询 ( 并 ); 数 据 更 新 (<br />
INSERT、UPDATE 和 DELETE( 标 准 格 式 )<br />
)。 要 求 能 够 用 SQL 语 句 表 达 基 本 表 的 创 建 、<br />
查 询 、 更 新 , 以 及 表 达 视 图 的 创 建 和 查 询 。<br />
了 解 : 计 算 模 型 (C/S 结 构 )<br />
174
熟 练 掌 握 :SQL 键 约 束 的 定 义 ; 参 照 完 整 性 约 束 定<br />
义 ; 单 值 约 束 (UNIQUE) 的 定 义 ; 属 性 值 (<br />
CHECK、DEFAULT) 约 束 定 义 。<br />
掌 握 :SQL 中 元 组 约 束 定 义 ; 参 照 完 整 性 的 维 护 。<br />
理 解 : 数 据 更 新 过 程 中 参 照 完 整 性 的 保 持 策 略 。<br />
了 解 : 数 据 库 对 象 --- 触 发 器 。<br />
175