数据库SQL—视图
定义视图
- CREATE VIEW <视图名> [ (<列名> , …, <列名>)] AS <查询表达式>
[WITH CHECK OPTION] - <视图名>对定义的视图命名, <列名>为<查询表达式>结果的诸列命名
- <查询表达式>通常是一个SELECT查询,其中不包含DISTINCT短语和ORDER BY子句
- WITH CHECK OPTION表示该视图是可更新的,并且对视图进行更新时要满足<查询表达式>的查询条件条件>与SELECT语句中的查询条件类似
PS:组成视图的属性列名要么全部省略要么全部指定。如果省略了视图的各个属性名,则由SELECT子句目标列中的各个字段组成。但在下列情况下必须明确指定组成视图的所有属性列名:
1)SELECT子句目标列中包含聚集函数或者列表达式;
2)SELECT子句目标列是‘*’;
3)多表连接时出现了同名属性列;
4)需要为视图中某个列定义更合适的名字
CREATE VIEW是说明语句,它创建一个视图,并将视图的定义存放在数据字典中,而定义中的<查询表达式>并不立即执行
CREATE VIEW SE_Students
AS SELECT Sno, Sname, Sex, Birthday, Dno
FROM Students
WHERE Speciality = ‘软件工程’
WITH CHECK OPTION;
//建立软件工程学生的视图SE_Students,属性列为 Sno, Sname, Sex, Birthday, Dno,并且包含专业为软件工程专业的所有学生的信息
PS:SE_Students是通过单个表Students上的选择和投影定义的视图,包含Students的码。通常,这种视图称为行列子集视图。行列子集视图是可更新的,因此我们使用了短语WITH CHECK OPTION,以便通过该视图插入学生元组时自动将属性Speciality上的值设置为“软件工程”。SELECT子句中的结果列都是属性,它们成为视图表的属性
CREATE VIEW EI_SC (Sno, Cno, Grade)
AS SELECT *
FROM SC
WHERE Sno IN (SELECT Sno
FROM Students
WHERE Dno= ‘IE’);
//建立信息工程学院学生的选课记录EI_SC,它与SC具有相同的属性,但只包含Dno为IE的学生
CREATE VIEW Student_Grades (Sno, Sname, Cname, Grade)
AS SELECT S.Sno, Sname, Cname, Grade
FROM Students S, SC, Courses C
WHERE S.Sno = SC.Sno AND C.Cno = SC.Cno;
//建立学生成绩视图Student_Grades,它包含如下属性:学号、学生姓名、课程名和成绩
CREATE VIEW CS_Student_Grades (Sno, Sname, Cname, Grade)
AS SELECT S.Sno, Sname, Cname, Grade
FROM Students S, Student_Grades SG
WHERE S.Sno = SG.Sno AND Speciality = ‘计算机科学与技术’;
//建立计算机科学与技术专业学生成绩视图CS_Student_Grades,它包含如下属性:学号、学生姓名、课程名和成绩
CREATE VIEW Student_Avg_Grades (Sno, Sname, Avg_Grade)
AS SELECT S.Sno, Sname, AVG (Grade)
FROM Students S, SC
WHERE S.Sno=SC.Sno
GROUP BY S.Sno, Sname;
//定义学生平均成绩视图Student_Avg_Grades,它包括如下属性:学生的学号、姓名和平均成绩(Avg_Grade)
删除视图
- 视图的删除语句的格式:DROP VIEW <视图名> [ CASCADE | RESTRICT ]
- 删除视图就是把视图的定义从数据字典中删除。CASCADE(级联)或RESTRICT(限制)是可选的,缺省时为RESTRICT
- 缺省时或者为RESTRICT时尽在无依赖时可删除
- CASCADE可强制删除被删除基于此视图的其他视图
DROP VIEW Student_Grades或DROP VIEW Student_Grades RESTRICT
不能删除例视图Student_Grades,因为视图CS_Student_Grades的定义依赖于它
DROP VIEW Student_Grades CASCADE将删除视图Student_Grades
并且级联地删除视图CS_Student_Grades
基于视图的查询
- 从用户角度讲,查询时使用视图与使用基本表并无区别
SELECT *
FROM SE_Students
WHERE Sex= ‘男’;
等价于
SELECT *
FROM (SELECT Sno, Sname, Sex, Birthday, Dno
FROM Students
WHERE Speciality = ‘软件工程’)
AS SE_Students (Sno, Sname, Sex, Birthday, Dno)
WHERE Sex= ‘男’;
//查询软件工程专业的男生
SELECT Sname, Cname, Grade
FROM Student_Grades
WHERE Sno=‘200605108’;
//查询学号为200605108的学生的各科成绩。要求显示学生姓名、课程名和成绩
基于视图的更新
- 视图的更新是指通过视图进行增、删、改操作
- 由于视图都是直接或间接基于基本表定义的,因此基于视图的更新最终要转换成基本表的更新
- 有些视图可以将更新唯一地转换成对定义它的基本表的更新,这种视图被称为可更新的视图
- 有些视图不能将更新唯一地转换成对定义它的基本表的更新,这种视图被称为不可更新视图
- 定义视图时加上WITH CHECK OPTION子句,系统在更新视图时会自动检查视图定义中的条件,不满足条件则拒绝更新
INSERT INTO SE_Students (Sno, Sname, Birthday, Sex, Dno)
VALUES (‘200605109’, ‘吴畅’, 1987-05-04, ‘女’, ‘EI’);
等价于
INSERT INTO Students (Sno, Sname, Birthday, Sex, Dno, Speciality)
VALUES (‘200605109’, ‘吴畅’, 1987-05-04, ‘女’, ‘EI’, ‘软件工程’);
//向软件工程专业学生的视图SE_Students(见例4.42)中插入一个新的记录
//学号为200605109,姓名为吴畅,出生年月1987-05-04,女性,所在院系EI。
DELETE FROM SE_Students
WHERE Sno=‘200705201’;
等价于:
DELETE FROM Students
WHERE Sno=‘200705201’ ;
//删除软件工程专业学号为200705201的学生
UPDATE SE_Students
SET Sname=‘李岩’
WHERE Sno=‘200705268’;
//将软件工程专业学号为200705268的学生姓名改为“李岩”
PS:如果学号为200705268的学生不是软件工程专业的学生,该语句不会修改任何元组
视图的作用
- 使用视图可以使一些查询表达更加简洁
- 视图提供了一定程度的逻辑独立性
- 视图可以起到安全保护作用
- 视图使得用户能够以不同角度看待相同的数据