CREATE VIEW

说明

CREATE VIEW 将定义一个表的视图.这个视图不是物理上实际存在(于磁盘)的.

语法

create_view ::=

check_option ::=

参数

OR REPLACE

指定 OR REPLACE 时,如果视图已经存在,会用新的定义去重建此视图

注解

没有其它对象依赖此视图时,才允许重建视图

OBJECT

指定 OBJECT 时,该视图自动创建一个数据类型,该数据类型代表对应该视图一行的元组类型(结构类型).因此,这时视图不能和一个现有数据类型同名。

FORCE

指定 FORCE 时,创建视图指定的基表如果不存在,也会强制创建视图。

viewname

视图名字,必须是合法的神通数据库标识符。

如果给出模式名称Schema.ViewName,那么该视图使用指定模式。否则使用该用户的默认模式。并且在某一模式中,视图名称必须唯一。

同一模式下,表、索引、视图、序列不能同名。

colname

视图的列名。不必与表(父视图)上的列名相同。

subquery

为视图提供数据的SELECT 查询语句。

参见 SELECT

CHECK OPTION

这个选项用于可更新视图,可以防止用户更改视图中不可见的数据。

如果使用了该选项,所有对视图的 INSERT 和 UPDATE 都要经过视图“CHECK OPTION 条件”的校验。如果没有通过校验,更新将被拒绝。

CHECK OPTION 可以保证所有INSERT 和 UPDATE 到视图的行,必定是该视图能 SELECT 出来的行。

CHECK OPTION 一共有两个可选参数 CASCADE 和 LOCAL。

默认是 CASCADE

只有在一个视图定义在另外一个视图上的时候CASCADE 和 LOCAL 才不同。

假定当前定义的视图为 V,当 V 的定义使用了CASCADE,则 V 的“CHECK OPTION 条件” = V 的“视图定义条件” AND V 的所有祖先视图的“视图定义条件”。

LOCAL

V 的“CHECK OPTION 条件” = V 的“视图定义条件” AND V 的父视图的“CHECK OPTION 条件”。

V1 defined on table T0
V2 defined on V1 WITH x CHECK OPTION
V3 defined on V2
V4 defined on V3 WITH y CHECK OPTION
V5 defined on V4

下表描述了x,y取不同值得时候,V1, V2, V3, V4, V5 的“CHECK OPTION 条件”,是由哪些视图的“视图定义条件” AND 而成的。

  x = LOCAL y = LOCAL x = CASCADED y = CASCADED x = LOCAL y = CASCADED x = CASCADED y = LOCAL
V1 None None None None
V2 V2 V2, V1 V2 V2, V1
V3 V2 V2, V1 V2 V2, V1
V4 V4, V2 V4,V3,V2,V1 V4,V3,V2,V1 V4,V2,V1
V5 V4, V2 V4,V3,V2,V1 V4,V3,V2,V1 V4,V2,V1

注:

CHECK OPTION 条件:有INSERT 和 UPDATE 到视图的行,必须满足此条件的约束。

父视图:如果视图 S 定义在视图 P 上,则P为父视图。

子视图:如果视图 S 定义在视图 P 上,则S为子视图。

祖先视图:

  1. 所有视图 S 的父视图 P 是 S 的祖先视图。

P 的祖先视图是 S 的祖先视图。

schema

视图所在的模式名字。

READ ONLY

视图是否可以更新。仅语法支持。

注解

创建的视图并不是物理上存在于磁盘的,它只是在数据字典中生成一个关于查询的定义。

除了DROP VIEW, CREATE VIEW之外的其他操作,最终被重写为对视图相关表的操作。

视图的作用

视图提供了数据的另一种访问方式,为数据库提供了灵活性。例如表的名字发生更改,在没有视图的情况下,所有依赖于原表的应用必须作相应的变更。此时可以在新表之上创建一张与原表同名的视图,则依赖于原表的应用都可以通过该视图操作原表,就好像原表没有改变过一样。

视图提供了一种权限控制机制。视图可以同时控制用户对行和列的访问权限。通过对不同类型的用户定义不同的视图,可以保证“敏感数据”的安全性。

当然视图也可以用来记录复杂的查询语句。通过创建视图,用户可以避免记忆和键入大量复杂的查询语句。

神通数据库可更新视图的条件

可更新视图是指那些可以执行UPDATE或者DELETE, 或者INSERT语句的视图。

可更新视图的必须满足:

  1. 视图定义在一张表上。

视图定义不含GROUP BY,HAVING子句。

视图定义不含层次查询。

视图定义中子查询不能引用视图基表。

在以上四个条件满足的情况下:

可UPDATE视图的条件:

如果视图至少含有一个"可UPDATE列",可该视图被称为"可UPDATE视图"。

可INSERT视图的条件:

  1. 视图的每一列都是"可UPDATE列"。

视图不包含重复的列。

可DELETE视图的条件:

无附加条件。

注:

满足以下两个条件的视图列是"可UPDATE列",否则被称为"不可UPDATE列"。

  1. 列定义不含有聚集函数,函数,表达式。

列对应的父视图的列可UPDATE。

示例

示例1: 创建视图

--  清理环境
DROP VIEW view1 CASCADE;
DROP TABLE tab1 CASCADE;


--  创建表并插入数据
CREATE TABLE tab1 (a INT, b INT, c INT);

INSERT INTO tab1 VALUES (1, 11, 111),
                        (2, 12, 112),
                        (3, 13, 113),
                        (4, 14, 114);


SELECT * FROM tab1 ORDER BY a, b, c;
A(int)      |B(int)      |C(int)      |
------------------------------------
1           |11          |111         |
------------------------------------
2           |12          |112         |
------------------------------------
3           |13          |113         |
------------------------------------
4           |14          |114         |
总数目:4


--  创建视图
CREATE VIEW view1 AS SELECT * FROM tab1 WHERE a % 2 = 0 ORDER BY a, b, c;


--  查询视图
SELECT * FROM view1;
A(int)      |B(int)      |C(int)      |
------------------------------------
2           |12          |112         |
------------------------------------
4           |14          |114         |
总数目:2

--  向视图插入数据
--  创建视图时未带有 WITH CHECK OPTION 选项
--  插入数据成功,但视图中查询不到这条记录(被 a % 2 = 0 过滤掉)
INSERT INTO view1 VALUES (5, 15, 115);


SELECT * FROM view1;
A(int)      |B(int)      |C(int)      |
------------------------------------
2           |12          |112         |
------------------------------------
4           |14          |114         |
总数目:2


--  删除视图和表
DROP VIEW view1;
DROP TABLE tab1;

示例2: 创建视图(带有 WITH CHECK OPTION 选项)

--  清理环境
DROP VIEW view2 CASCADE;
DROP TABLE tab2 CASCADE;


--  创建表并插入数据
CREATE TABLE tab2 (a INT, b INT, c INT);

INSERT INTO tab2 VALUES (1, 11, 111),
                        (2, 12, 112),
                        (3, 13, 113),
                        (4, 14, 114);


SELECT * FROM tab2 ORDER BY a, b, c;
A(int)      |B(int)      |C(int)      |
------------------------------------
1           |11          |111         |
------------------------------------
2           |12          |112         |
------------------------------------
3           |13          |113         |
------------------------------------
4           |14          |114         |
总数目:4


--  创建视图
CREATE VIEW view2 AS SELECT * FROM tab2 WHERE a % 2 = 0 ORDER BY a, b, c WITH CHECK OPTION;


--  查询视图
SELECT * FROM view2;
A(int)      |B(int)      |C(int)      |
------------------------------------
2           |12          |112         |
------------------------------------
4           |14          |114         |
总数目:2

--  向视图插入数据
--  创建视图时带有 WITH CHECK OPTION 选项
--  数据不满足视图 a % 2 = 0 筛选条件,插入数据失败
INSERT INTO view2 VALUES (5, 15, 115);
ERROR, 视图上的CHECK OPTION约束检查失败, 



SELECT * FROM view2;
A(int)      |B(int)      |C(int)      |
------------------------------------
2           |12          |112         |
------------------------------------
4           |14          |114         |
总数目:2


--  删除视图和表
DROP VIEW view2;
DROP TABLE tab2;

示例3: 不可更新视图

--  清理环境
DROP VIEW view3 CASCADE;
DROP TABLE tab3 CASCADE;


--  创建表并插入数据
CREATE TABLE tab3 (a INT, b INT, c INT);

INSERT INTO tab3 VALUES (1, 11, 111),
                        (2, 12, 112),
                        (3, 13, 113),
                        (4, 14, 114);


SELECT * FROM tab3 ORDER BY a, b, c;
A(int)      |B(int)      |C(int)      |
------------------------------------
1           |11          |111         |
------------------------------------
2           |12          |112         |
------------------------------------
3           |13          |113         |
------------------------------------
4           |14          |114         |
总数目:4


--  创建视图
--  视图定义含有 GROUP BY —— 视图不可更新
CREATE VIEW view3 AS SELECT MAX(a) FROM tab3 GROUP BY b;


--  查询视图
SELECT * FROM view3;
MAX(int)      |
--------------
1             |
--------------
2             |
--------------
3             |
--------------
4             |
总数目:4

--  视图不可更新 —— 插入数据失败
INSERT INTO view3 VALUES (5);
ERROR, 视图不可更新, Please provide an INSTEAD OF trigger.



SELECT * FROM view3;
MAX(int)      |
--------------
1             |
--------------
2             |
--------------
3             |
--------------
4             |
总数目:4


--  删除视图和表
DROP VIEW view3;
DROP TABLE tab3;

示例4: 特殊的不可 INSERT 视图

--  清理环境
DROP VIEW view4 CASCADE;
DROP TABLE tab4 CASCADE;


--  创建表并插入数据
CREATE TABLE tab4 (a INT, b INT, c INT);

INSERT INTO tab4 VALUES (1, 11, 111),
                        (2, 12, 112),
                        (3, 13, 113),
                        (4, 14, 114);


SELECT * FROM tab4 ORDER BY a, b, c;
A(int)      |B(int)      |C(int)      |
------------------------------------
1           |11          |111         |
------------------------------------
2           |12          |112         |
------------------------------------
3           |13          |113         |
------------------------------------
4           |14          |114         |
总数目:4


--  创建视图
CREATE VIEW view4 AS SELECT a as a1, a as a2 FROM tab4 ORDER BY a;


--  查询视图
SELECT * FROM view4;
A1(int)      |A2(int)      |
--------------------------
1            |1            |
--------------------------
2            |2            |
--------------------------
3            |3            |
--------------------------
4            |4            |
总数目:4

--  视图中的两列实际上是同一张表的同一列,插入数据失败
INSERT INTO view4 VALUES (5, 5);
ERROR, Multiple assignments to same attribute "A2"



SELECT * FROM view4;
A1(int)      |A2(int)      |
--------------------------
1            |1            |
--------------------------
2            |2            |
--------------------------
3            |3            |
--------------------------
4            |4            |
总数目:4


--  删除视图和表
DROP VIEW view4;
DROP TABLE tab4;