视 图
更新视图
更新视图是指通过视图来插入(INSERT)、删除(DELETE)和修改(UPDATE)数据。
由于视图是不实际存储数据的虚表,因此对视图的更新最终要转换为对基本表的更新。像查询视图那样,对视图的更新操作也是通过视图消解,转换为对基本表的更新操作。
为防止用户通过视图对数据进行增加、删除、修改时,有意无意地对不属于视图范围内的基本表数据进行操作,可在定义视图时加上WITH CHECK OPTION子句。这样在视图上增、删、改数据时,关系数据库管理系统会检查视图定义中的条件,若不满足条件则拒绝执行该操作。
【例1】将信息系学生视图IS_Student中学号为“201215122”的学生姓名改为“刘辰”。
UPDATE IS_Student
SET Sname='刘辰'
WHERE Sno=’201215122';
转换后的更新语句为
UPDATE Student
SET Sname=刘辰'
WHERE Sno=’201215122'
AND Sdept=’IS';
【例2】向信息系学生视图IS_Student 中插入一个新的学生记录,其中学号为“201215129”,姓名为“赵新”,年龄为20岁。

这里系统自动将系名'IS"放入VALUES子句中。
【例3】删除信息系学生视图IS_Student中学号为“201215129”的记录。
DELETE
FROM IS_Student
WHERE Sno='201215129';
转换为对基本表的更新:
DELETE
FROM Student
WHERE Sno='201215129'
AND Sdept='IS';
在关系数据库中,并不是所有的视图都是可更新的,因为有些视图的更新不能唯一地有意义地转换成对相应基本表的更新。
例如,定义的视图S_G是由学号和平均成绩两个属性列组成的,其中平均成绩一项是由Student表中对元组分组后计算平均值得来的:
CREATE VIEW S_G(Sno,Gavg)
AS
SELECT Sno,AVG(Grade)
FROM SC
GROUP BY Sno;
如果想把视图S_G中学号为“201215121”的学生的平均成绩改成90分,SQL语句如下:
UPDATE S_G
SET Gavg=90
WHERE Sno='201215121';
但这个对视图的更新是无法转换成对基本表SC的更新的,因为系统无法修改各科成绩,以使平均成绩成为90。所以S_G视图是不可更新的。
一般地,行列子集视图是可更新的。除行列子集视图外,有些视图理论上是可更新的,但它们的确切特征还是尚待研究的课题。还有些视图从理论上就是不可更新的。
目前,各个关系数据库管理系统一般都只允许对行列子集视图进行更新,而且各个系统对视图的更新还有更进一步的规定。由于各系统实现方法上的差异,这些规定也不尽相同。
例如,DB2规定:
1.若视图是由两个以上基本表导出的,则此视图不允许更新。
2.若视图的字段来自字段表达式或常数,则不允许对此视图执行INSERT和UPDATE操作,但允许执行DELETE操作。
3.若视图的字段来自聚集函数,则此视图不允许更新。
4.若视图定义中含有GROUPBY子句,则此视图不允许更新。
5.若视图定义中含有DISTINCT短语,则此视图不允许更新。
6.若视图定义中有嵌套查询,并且内层查询的FROM子句中涉及的表也是导出该视图的基本表,则此视图不允许更新。例如,将SC表中成绩在平均成绩之上的元组定义成一个视图GOOD_SC:
CREATE VIEW GOOD_SC
AS
SELECT Sno,Cno,Grade
FROM SC
WHERE Grade >
(SELECT AVG(Grade)
FROM SC);
导出视图GOOD_SC的基本表是SC,内层查询中涉及的表也是SC,所以视图GOOD_SC是不允许更新的。
7.一个不允许更新的视图上定义的视图也不允许更新。
应该指出的是,不可更新的视图与不允许更新的视图是两个不同的概念。前者指理论上已证明其是不可更新的视图。后者指实际系统中不支持其更新,但它本身有可能是可更新的视图。
视图的作用
视图最终是定义在基本表之上的,对视图的一切操作最终也要转换为对基本表的操作。而且对于非行列子集视图进行查询或更新时还有可能出现问题。既然如此,为什么还要定义视图呢?这是因为合理使用视图能够带来许多好处。
①视图能够简化用户的操作
视图机制使用户可以将注意力集中在所关心的数据上。如果这些数据不是直接来自基本表,则可以通过定义视图使数据库看起来结构简单、清晰,并且可以简化用户的数据查询操作。
例如,那些定义了若干张表连接的视图就将表与表之间的连接操作对用户隐蔽起来了。换句话说,用户所做的只是对一个虚表的简单查询,而这个虚表是怎样得来的,用户无须了解。
②视图使用户能以多种角度看待同一数据
视图机制能使不同的用户以不同的方式看待同一数据,当许多不同种类的用户共享同一个数据库时,这种灵活性是非常重要的。
③视图对重构数据库提供了一定程度的逻辑独立性
第1章中已经介绍过数据的物理独立性与逻辑独立性的概念。数据的物理独立性是指用户的应用程序不依赖于数据库的物理结构。数据的逻辑独立性是指当数据库重构造时,如增加新的关系或对原有关系增加新的字段等,用户的应用程序不会受影响。层次数据库和网状数据库一般能较好地支持数据的物理独立性,而对于逻辑独立性则不能完全地支持。
在关系数据库中,数据库的重构往往是不可避免的。重构数据库最常见的是将一个基本表“垂直”地分成多个基本表。例如:将学生关系
Student(Sno, Sname, Ssex, Sage, Sdept)
分为SX(Sno,Sname,Sage)和SY(Sno, Ssex, Sdept)两个关系。这时原表Student为SX表和SY表自然连接的结果。如果建立一个视图Student:
CREATE VIEW Student(Sno, Sname, Ssex, Sage, Sdept)
AS
SELECT SX.Sno, SX.Sname, SY.Ssex, SX.Sage, SY.Sdept
FROM SX,SY
WHERE SX.Sno=SY.Sno;
这样尽管数据库的逻辑结构改变了(变为SX和SY两个表),但应用程序不必修改,因为新建立的视图定义为用户原来的关系,使用户的外模式保持不变,用户的应用程序通过视图仍然能够查找数据。
当然,视图只能在一定程度上提供数据的逻辑独立性,比如由于对视图的更新是有条件的,因此应用程序中修改数据的语句可能仍会因基本表结构的改变而需要做相应修改。
④视图能够对机密数据提供安全保护
有了视图机制,就可以在设计数据库应用系统时对不同的用户定义不同的视图,使机密数据不出现在不应看到这些数据的用户视图上。这样视图机制就自动提供了对机密数据的安全保护功能。例如,Student表涉及全校15个院系的学生数据,可以在其上定义15个视图,每个视图只包含一个院系的学生数据,并只允许每个院系的主任查询和修改本院系的学生视图。
⑤适当利用视图可以更清晰地表达查询
例如,经常需要执行这样的查询“对每个同学找出他获得最高成绩的课程号”。可以先定义一个视图,求出每个同学获得的最高成绩:








