视图以经过定制的方式显示来自一个或多个表的数据,视图可以视为“虚拟表”或“存储的查询”,创建视图所依据的表称为“基表”。
视图的有如下优点:
提供了另外一种级别的表安全性隐藏的数据的复杂性简化的用户的SQL命令隔离基表结构的改变通过重命名列,从另一个角度提供数据首先创建如下 student 基表:
create table student( sno number primary key, sname varchar2(50) ); insert into student values(1, '张三'); insert into student values(2, '李四');然后创建如下视图,注意我们对查询语句加了 where sno = 1 的限定条件:
create view view1 as select * from student where sno = 1视图 view1 创建完成之后,执行如下更新语句。下述的更新语句会导致对视图 view1 的查询结果变为空。
update view1 set sno = 3 where sno = 1为了避免上述的情况发生,可以在创建视图语句的后面加上 with check option 来对视图的数据更新进行校验,如下所示:
create view view2 as select * from student where sno = 1 with check option此时在进行上述的更新操作,则会报如下的错误:
ORA-01402: view WITH CHECK OPTION where-clause violation with read only 标识只允许创建一个可读的视图,视图不可进行增删改操作。视图也可以进行连接查询,具体使用方法大体与表的连接查询一致,这里不再赘述。
在视图上也可以使用修改数据的DML语句,如INSERT、UPDATE和DELETE。视图上的DML语句有如下限制:
只能修改一个底层的基表如果修改违反了基表的约束条件,则无法更新视图如果视图包含连接操作符、DISTINCT 关键字、集合操作符、聚合函数或 GROUP BY 子句,则将无法更新视图如果视图包含伪列或表达式,则将无法更新视图前面说过,在对视图的 DML 操作是只能修改一个底层的基表,那么如果视图是多表视图的时候,进行更新操作会发生怎样的情况呢?查看如下语句:
-- 创建基表 student1 create table student1 (sno number(6), birthday date, sname varchar2(10)); insert into student1 values(1, '11-1月-81', '张三'); insert into student1 values(2, '10-3月-82', '李四'); insert into student1 values(3, '06-1月-83', '王五'); -- 创建基表 address1 create table address1(sno number(6), zz varchar2(10)); insert into address1 values(1, '郑州'); insert into address1 values(2, '开封'); insert into address1 values(3, '洛阳'); -- 创建多表视图 create view view_student1_address1 as select s.sno sno1, s.sname, a.sno sno2, a.zz from student1 s, address1 a where s.sno = a.sno; --查询多表视图 SQL> select * from view_student1_address1; SNO1 SNAME SNO2 ZZ ------- ---------- ------- ---------- 1 张三 1 郑州 2 李四 2 开封 3 王五 3 洛阳 -- 更新 sno1 为 1 的记录 update view_student1_address1 set sno1 = 11 where sno1 = 1执行上述更新语句之后,会报如下的错误。也就是说不能修改非键保留表的视图的列。
ORA-01779: cannot modify a column which maps to a non key-preserved table为了能够修改多表视图的一个底层的基表(DML 的限制条件,只能是一个基表),我们可以通过建立键保留表来实现。具体查看如下语句:
create table student(sno number(6) primary key, sname varchar2(10), deptno char(3)); insert into student values(1, '张三', '001'); insert into student values(2, '李四', '001'); insert into student values(3, '王五', '002'); create table department(deptno char(3) primary key, deptname varchar2(20)); insert into department values('001', '中文系'); insert into department values('001', '数学系'); insert into department values('002', '英语系'); CREATE VIEW view_stu_dept AS select s.sno, s.sname, s.deptno, d.deptname from student s, department d where s.deptno = d.deptno;不同与上述的示例,此时建立的 student 和 department 表都包含主键,此时建立的视图可以通过更新语句对保留表的列进行更新操作。
上述视图建立的键保留表即为 stdent,也就是我们仅能对视图 view_stu_dept 中来自 student 表的列进行更新操作,对于来自 department 表的列则不可以进行相应的操作。
视图中可以使用单行函数、分组函数和表达式,不过必须为使用函数或者表达式的字段设置别名,示例如下:
CREATE VIEW item_view AS SELECT itemcode, LOWER(itemdesc) item_desc -- 设置别名 FROM itemfile;语法如下:
drop view 视图名