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_

一个将为视图提供行和列的SELECT 或VALUES语句。

注意

使用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子句也是一个扩展。

又见

ALTER VIEW, DROP VIEW, CREATE MATERIALIZED VIEW