0%

oracle 11g 的视图

1. 含义

视图以经过定制的方式显示来自一个或多个表的数据,视图可以视为“虚拟表”或“存储的查询”,创建视图所依据的表称为“基表”。

视图的有如下优点:

  • 提供了另外一种级别的表安全性
  • 隐藏的数据的复杂性
  • 简化的用户的SQL命令
  • 隔离基表结构的改变
  • 通过重命名列,从另一个角度提供数据

2. 语法

1
2
3
4
CREATE [OR REPLACE] [FORCE] VIEW view_name [(alias[, alias]...)] 
AS select_statement
[WITH CHECK OPTION]
[WITH READ ONLY];
  • force 参数表示强制创建视图,例如下面的示例,视图 view1 的基表 address 并不存在。但是在使用 force 参数后依旧可以创建。但是此时视图并不可以使用,只有当基表 address 创建完成后才可以使用视图。
1
2
3
-- 强制创建视图,即是视图的基表 address 不存在。
create force view view1
as select * from address;
  • with check option 顾名思义即是对视图的数据进行校验。视图是可以进行 update 等更新操作的,因此可能会由于更新操作而导致原有的视图失效。

首先创建如下 student 基表:

1
2
3
4
5
6
create table student(
sno number primary key,
sname varchar2(50)
);
insert into student values(1, '张三');
insert into student values(2, '李四');

然后创建如下视图,注意我们对查询语句加了 where sno = 1 的限定条件:

1
2
3
create view view1
as
select * from student where sno = 1

视图 view1 创建完成之后,执行如下更新语句。下述的更新语句会导致对视图 view1 的查询结果变为空。

1
update view1 set sno = 3 where sno = 1

为了避免上述的情况发生,可以在创建视图语句的后面加上 with check option 来对视图的数据更新进行校验,如下所示:

1
2
3
create view view2
as select * from student where sno = 1
with check option

此时在进行上述的更新操作,则会报如下的错误:

1
ORA-01402: view WITH CHECK OPTION where-clause violation
  • with read only 标识只允许创建一个可读的视图,视图不可进行增删改操作。

3. 连接

视图也可以进行连接查询,具体使用方法大体与表的连接查询一致,这里不再赘述。

4. 视图的 DML

在视图上也可以使用修改数据的DML语句,如INSERT、UPDATE和DELETE。视图上的DML语句有如下限制:

  • 只能修改一个底层的基表
  • 如果修改违反了基表的约束条件,则无法更新视图
  • 如果视图包含连接操作符、DISTINCT 关键字、集合操作符、聚合函数或 GROUP BY 子句,则将无法更新视图
  • 如果视图包含伪列或表达式,则将无法更新视图

5. 键保留表

前面说过,在对视图的 DML 操作是只能修改一个底层的基表,那么如果视图是多表视图的时候,进行更新操作会发生怎样的情况呢?查看如下语句:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
-- 创建基表 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

执行上述更新语句之后,会报如下的错误。也就是说不能修改非键保留表的视图的列。

1
ORA-01779: cannot modify a column which maps to a non key-preserved table

为了能够修改多表视图的一个底层的基表(DML 的限制条件,只能是一个基表),我们可以通过建立键保留表来实现。具体查看如下语句:

1
2
3
4
5
6
7
8
9
10
11
12
13
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 表的列则不可以进行相应的操作。

6. 视图中的函数

视图中可以使用单行函数、分组函数和表达式,不过必须为使用函数或者表达式的字段设置别名,示例如下:

1
2
3
CREATE VIEW item_view AS 
SELECT itemcode, LOWER(itemdesc) item_desc -- 设置别名
FROM itemfile;

7. 删除视图

语法如下:

1
drop view 视图名
------ 本文结束------