CREATE VIEW
Name
CREATE VIEW -- 定义一个新视图
Synopsis
CREATE [ OR REPLACE ] [ TEMP | TEMPORARY ] [ RECURSIVE ] VIEW _name_ [ ( _column_name_ [, ...] ) ]
[ WITH ( _view_option_name_ [= _view_option_value_] [, ... ] ) ]
AS _query_
描述
CREATE VIEW
定义一个查询的视图。 这个视图不是物理上实际存在的,并且在该视图每次被引用的时候都会运行一次查询。
CREATE OR REPLACE VIEW
类似,不过如果一个同名的视图已经存在, 那么将替换它。新查询必须生成与现有视图查询生成的字段相同的字段(也就是, 相同的字段名字,相同的顺序和相同的数据类型),但是可能添加额外的字段到列表的结尾。 该计算导致输出字段可能完全不同。
如果给出了一个模式名(比如CREATE VIEW myschema.myview ...
), 那么该视图将在指定的模式中创建,否则将在当前模式中创建。 临时视图存在于一个特殊的模式里,所以创建临时视图的时候,不能给出模式名。 新视图名字必需和同一模式中任何其它视图、表、序列、索引或外部表的名字不同。
参数
TEMPORARY
或 TEMP
如果声明了这个子句,那么视图就以临时视图的方式创建。 临时视图在当前会话结束的时候将被自动删除。当前会话中,在临时视图存在的期间, 将无法看到现有的同名关系,除非用模式修饰的名字引用它们。
如果视图引用的任何基础表是临时的,那么视图将被创建为临时的 (不管是否声明了TEMPORARY
)。
RECURSIVE
创建一个递归的视图。语法
CREATE RECURSIVE VIEW _name_ (_columns_) AS SELECT _..._;
等同于
CREATE VIEW _name_ AS WITH RECURSIVE _name_ (_columns_) AS (SELECT _..._) SELECT _columns_ FROM _name_;
必须为一个递归的视图指定一个视图字段列表。
_name_
所要创建的视图名称(可以有模式修饰)。
_column_name_
一个可选的名字列表,用作视图的字段名。如果没有给出,字段名取自查询。
WITH (
_view_option_name_
[= _view_option_value_
] [, ... ] )
该子句为视图指定选项参数;目前,唯一支持的参数名是security_barrier
, 当视图打算提供行级安全时,应该启用该参数。参阅Section 38.5 获取全部细节。
_query_
注意
使用DROP VIEW语句删除视图。
请注意视图字段的名字和类型不一定是你们期望的那样。比如,
CREATE VIEW vista AS SELECT 'Hello World';
在两个方面很糟糕:字段名缺省是?column?
并且字段的数据类型缺省是unknown
。 如果你想视图的结果是一个字符串文本,那么请像下面这样使用:
CREATE VIEW vista AS SELECT text 'Hello World' AS hello;
对视图引用的表的访问的权限由视图的所有者决定。在一些情况下, 这可用于提供安全但是限制访问底层表。不过,不是所有视图对于篡改都是安全的; 参阅Section 38.5获取细节。 在视图里调用的函数当作他们直接从使用视图的查询里调用看待。因此, 视图的用户必须有调用视图使用的所有函数的权限。
当CREATE OR REPLACE VIEW
用在一个现有的视图上时, 只改变了视图定义的SELECT规则。其他视图属性,包括所有权、权限和非SELECT规则, 保持不变。要替换视图,你必须拥有该视图(包括成为拥有者角色的一员)。
可更新的视图
简单的视图是自动可更新的:系统允许INSERT
、UPDATE
和DELETE
语句和在规则表上一样的方式在视图上使用。 如果视图满足所有下列的条件,那么就是自动可更新的:
视图在它的
FROM
列表中必须只有一个条目, 该条目必须是一个表或其他可更新视图。视图定义必须没有在顶级包含
WITH
、DISTINCT
、GROUP BY
、HAVING
、LIMIT
或OFFSET
子句。视图定义必须没有在顶级包含集合运算(
UNION
、INTERSECT
或EXCEPT
)。视图的选择列表中的所有字段必须简单的引用底层关系的字段。 它们不能是表达式、字面值或函数。也不能引用系统字段。
在视图的选择列表中,底层关系的字段出现不能超过一次。
视图必须没有
security_barrier
属性。
如果视图是自动可更新的,那么系统将转换视图上的任意INSERT
、 UPDATE
或DELETE
语句为相应的底层基本关系上的语句。
如果一个自动可更新的视图包含一个WHERE
条件, 那么该条件约束基本关系的哪些行可以被视图上的UPDATE
和DELETE
语句修改。不过,允许UPDATE
更改一个行,所以它不再满足WHERE
条件,并且因此不再通过视图可见。 相似的,INSERT
命令可以潜在的插入不满足WHERE
条件的基本关系行,并且因此不能通过视图可见。
不满足所有这些条件的更复杂的视图缺省是只读的:系统将不允许在该视图上插入、 更新或删除。可以通过在该视图上创建INSTEAD OF
触发器获得可更新视图的效果, 该触发器必须转换在该视图上的尝试插入等为其他表上的适当动作。更多信息请参见 CREATE TRIGGER。还有一种可能性是创建规则 (参阅CREATE RULE),但是实际上触发器更容易理解和正确使用。
请注意,用户在视图上执行插入、更新或删除必须在该视图上有相应的插入、 更新或删除的权限。此外,视图的所有者必须在底层基础关系上有相关的权限, 但是执行更新的用户不需要在底层基础关系上的任何权限 (参阅Section 38.5)。
例子
创建一个由所有喜剧电影组成的视图:
CREATE VIEW comedies AS
SELECT *
FROM films
WHERE kind = 'Comedy';
这将创建一个视图,在视图创建的时候包含film
表中字段。 尽管用*
创建了该视图,但是后来添加到表中的字段将不会是视图的一部分。
创建一个由数字1到100组成的递归的视图:
CREATE RECURSIVE VIEW nums_1_100 (n) AS
VALUES (1)
UNION ALL
SELECT n+1 FROM nums_1_100 WHERE n < 100;
兼容性
SQL 标准为CREATE VIEW
声明了一些附加的功能:
CREATE VIEW _name_ [ ( _column_name_ [, ...] ) ]
AS _query_
[ WITH [ CASCADED | LOCAL ] CHECK OPTION ]
完整的 SQL 命令可选的子句是:
CHECK OPTION
这个选项控制自动可更新视图的行为。给出时,对视图的INSERT
和UPDATE
都要检查以确保新行满足视图定义的条件(也就是说, 新行应该可以通过视图看到)。如果没有通过检查,更新将被拒绝。 没有CHECK OPTION
,允许对视图的INSERT
和UPDATE
命令创建通过该视图不可见的行。 (后者的行为当前只有PostgreSQL提供。)
LOCAL
对这个视图进行完整性检查。
CASCADED
对此视图和任何相关视图进行完整性检查。在既没有声明CASCADED
也没有声明LOCAL
时,假设为CASCADED
。
CREATE OR REPLACE VIEW
是PostgreSQL 的扩展。临时视图的概念也是扩展。WITH
子句也是一个扩展。