7.5 视图的定义
视图是从一个或几个基表(或视图)导出的虚拟表。视图中行和列数据来源于由定义视图的查询所引用的表,并且在引用视图时动态生成
7.5.1 视图概念
- 视图是从一个或者多个表及其他视图中通过SELECT语句导出的虚拟表。视图与数据表一样包含一些列带有名称的列和行的数据,但是,视图所对应数据的行和列数据来自定义视图的查询所引用的表,并且在引用视图时动态生成。
- 视图的行为和数据表类似,可以对其进行查看、修改和删除,也可通过视图实现对基表数据的查询与修改。
- 视图为数据库用户提供了很多的便利,主要包括以下几个方面。
- 简化数据查询和处理。
- 屏蔽数据库的复杂性。
- 安全性。可以只授予用户访问视图的权限,而不授予访问表的权限,这样就提高了数据库的安全性。
7.5.2 创建视图
- 使用SQL Server Management Studio创建视图
- 使用Transact-SQL语句创建视图
语法格式如下:
create view [database_name.][schema_name.]
view_name[(column[,…n])]
[with view_attribute[,…n]]
as select_statement
[with check option]
其中view_attribute定义为:
{encryption|schemabinding|view_metadata}
例7.11
编程在 teaching 数据库中创建一个名称为 v_course 的视图,包含所有类别为“必修”的课程信息。
use teaching
go
create view v_course
as select * from course
where type=‘必修’
例7.12
编程在 teaching 数据库中创建一个名称为 v_final 的视图,包含学生学号、姓名、课程号、课程名和期末成绩,按学号升序排序,相同学号的记录按课程号升序排序。
create view v_final as
select top(100) percent student.studentno,
student.sname,course.courseno,course.cname,score.final
from student,course,score
where student.studentno=score.studentno and
course.courseno=score.courseno
order by student.studentno,course.courseno
例7.13
编程在 teaching 数据中创建一个名称为 v_max 的视图,查询每个班最高分的课程名和分数,按班级号升序排序。
create view v_max as
select top 10 classno,cname,max(final) as max
from student s,score sc,course c
where sc.courseno=c.courseno and
s.studentno=sc.studentno and final is not null
group by classno,cname
order by classno - 通过视图查看数据
语法格式如下:
select * from view_name
例7.14
通过 v_final 和 v_course 视图查询所有学生的学号、姓名和必修课的总学分。
select studentno as ‘学号’,sname as ‘姓名’,sum(credit) as ‘必修课总学分’
from v_final,v_course
where v_final.courseno=v_course.courseno
group by studentno,sname
7.5.3 查看视图信息
- 使用系统存储过程查看视图信息
- sp_help:用于显示数据库对象或数据类型的基本信息。语法格式如下:
sp_help [[@objname=]‘name’] - sp_helptext:用于显示用户定义规则、默认值、未加密的存储过程、触发器、视图等数据对象的定义信息,语法格式如下:
sp_helptext [@objname=]‘name’ - sp_depends:用于显示有关数据库对象依赖关系的信息。语法格式如下:
sp_depends[@objname=]‘object’
- 使用系统表查看视图信息
例7.15
利用 sysobjects 和 syscomments 两个系统表查看 v_avg 视图的名称、ID和定义视图的文本信息。
select
sysobjects.name,sysobjects.id,syscomments.text
from sysobjects,syscomments
where sysobjects.name=‘v_avg’ and
sysobjects.type=‘v’ and
sysobjects.id=syscomments.id
7.6 视图的修改
7.6.1 在SQL Server Management Studio中修改视图
- 语法格式如下:
alter view [database_name.][shema_name.]
view_name[(column[,statement [with check option]
例7.16
使用ALTER VIEW语句修改 v_final 视图,使其包含所有学生姓名、课程名和期末成绩,按姓名升序排序。
alter view v_final as
select top(100) percent
student.studentno,sname,cname,final
from student,course,score
where student,course,score
where student.studentno=score.studentno and
course.courseno=score.courseno
order by student.studentno
例7.17
使用ALTER VIEW语句修改v_avg视图,将其改为加密方式,以确保视图的安全性。
alter view v_avg
with encryption as
select top(100)percent student.sname,avg(score.final) as average
from score inner join student on score.studentno=student.studentno
where student.classno=‘090501’ and score.final is not null
group by student.sname having(score.final)>60
order by average desc
–使用系统存储过程sp_helptext查看已加密视图的定义信息
exec sp_helptext v_avg
7.6.3 视图重命名
语法格式如下:
sp_rename[@objname=]‘object_name’,
[@newname=]‘new_name’
[,[@objtype=] ‘object_type’]
例如
exec sp_rename ‘v_成绩’,‘v_final’
7.6.4 删除视图
语法格式如下:
drop view [schema_name] view_name[…,n][;]
7.7 通过视图修改数据
- 通过视图向基表中插入数据
(1)使用INSERT语句向数据表中插入数据时,用户必须具备插入数据的相关权限。
(2)进行插入操作的视图只能引用一个基表的列。
(3) 视图中包含的列必须直接引用表列中的基础数据,不能通过计算或聚合函数等方式派生。
(4)INSERT语句须为不允许为空值,且没有DEFAULT定义的基表中的所有列指定值。这将确保基表中所有需要值的列都可以获取值。
(5)在基表中插入的数据必须符合在相关列上定义的约束条件,如是否为空、约束及默认值定义等。
(6)视图中不能包含DISTINCT、GROUP BY或HAVING子句。
(7)如果在视图定义中使用了WITH CHECK OPTION子句,则该子句将检查插入的数据是否符合视图定义中SELECT语句所设置的条件,如果插入的数据不符合该条件,SQL Server会拒绝插入数据,并显示错误。
例7.18
通过视图 v_course 向基表 course 中插入数据 (‘c05129’, ‘数据库编程’, ‘必修’, 64, 4)。
insert into v_course
values(‘c05129’,‘数据库编程’,‘必修’,64,4)
select * from course
例7.19
编程在teaching数据中创建一个名称为v_sex的视图,包含所有性别为“女”的学生的学号、姓名、性别、出生日期和班级编号,需限制插入数据中性别必须为“女”。
create view v_sex as
select studentno,sname,sex,birthday,classno
from student
where sex=‘女’ with check option - 通过视图更新基表中的数据
在视图上可以使用UPDATE语句实现对于基表中相关记录的修改,但修改操作必须符合在视图中插入数据的相关规则,并且需要遵守以下规则:
- 修改视图中的数据时,不能同时修改两个或者多个基表。
- 当视图来自多个基表时,通常只能对非主属性进行修改操作。
- 视图中被修改的列必须是直接引用基表的列,不能通过计算或聚合函数等方式派生。
例7.21
通过视图v_course将基表course课程号为c05129的课程名称修改为’数据库应用与开发’。
use teaching
update v_course
set cname=‘数据库应用与开发’
where courseno=‘c05129’
select * from course
例7.22
通过视图v_final 将基表 score 中学号为 0925121107 的学生梁欣选修的课程号为c05129的C语言课程的期末成绩修改为60分。
update v_final set final=60
where studentno=‘0925121107’ and courseno=‘c05109’
select s.studentno,sname,c.courseno,cname,final
from student s course c,score sc
where s.studentno=sc.studentno and c.courseno=sc.courseno
例7.23
通过视图v_final 将基表student和score中学号为0925121107,选修的课程号为c05129的学生姓名修改为李静,期末成绩修改为60分。
UPDATE v_final SET sname=‘李静’,final=60
WHERE studentno=‘0925121107’ AND courseno=‘c05109’
例7.24
通过视图v_sex删除基表student中学号为‘ 0938211038’的学生记录。
DELETE FROM v_sex
WHERE studentno=‘0938211038’
GO
SELECT * FROM student
例7.25
通过视图 v_course 删除基表 course 中课程号为 c05109 的课程记录。
DELETE FROM v_course
WHERE courseno=‘c05109’
附件:
使用到的数据库:
https://pan.baidu.com/s/1Lmbw_qSmC04wnPUUgwSKRA
提取码:djsz