由create table定义的表:以物理形式存在,实际存储在数据库中
视图:虚拟的,并不是一个真正存在的表
1.视图定义
CREATE VIEW <视图名> AS <视图定义>
例1.
CREATE VIEW ParamountMovies AS SELECT title, year FROM Movies WHERE studioName = ‘Paramount‘;
例2.涉及多个表
CREATE VIEW MovieProd AS SELECT title, name FROM Movies, MovieExec WHERE producerC# = cert#;
例3.涉及属性重命名
CREATE VIEW MovieProd(movieTitle, prodName) AS SELECT title, name FROM Movies, MovieExec WHERE producerC# = cert#;
2.视图查询
跟查询普通的表一样。
3.视图更新
理论上,视图的更新没有意义,因为它是虚拟的。
但是,特别简单的视图可以更新,其本质是更新了与视图相关的实体表。
DROP VIEW ParamountMovies;
删除视图不会影响实体表,但是删除了实体表会导致相应的视图不可用。
只有简单的视图才可以更新,说白了,就是视图简单到可以更新视图的数据明确的找到实体表应该调整的地方,让实体表做真正的更新。
可更新视图的条件:
1.视图仅从单个关系R中选出
2.用SELECT而非SELECT DISTINCT选出
3.WHERE 子句中不能使用R
4.SELECT中的属性必须足够多,保证对R插入时可以通过默认值的填充剩下的值。
语句跟普通的插入更新语句相同。
对下面的视图:
CREATE VIEW ParamountMovies AS SELECT title, year FROM Movies WHERE studioName = ‘Paramount‘;
采用插入操作
INSERT INTO ParamountMovies VALUES(‘Star Trek‘,1979);
由于并没有在插入时指明studioName = ‘Paramount‘,导致插入到实体表R中的语句无法在视图中被检索出来。这是显然不合理的。
解决方法:
1.定义视图时就把studioName属性加入
2.采用替换触发器
CREATE TRIGGER ParamountInsert INSTEAD OF INSERT ON ParamountMovies REFERENCING NEW ROW AS NewRow FOR EACH ROW INSERT INTO Movies(title, year, studioName) VALUES(NewRow.title, NewRow.year, ‘Paramount‘);
INSTEAD OF表明替换:即原本的操作不会被执行,而是执行触发器中的动作!
原文:http://www.cnblogs.com/dplearning/p/4887965.html