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 ...), 那么该视图将在指定的模式中创建,否则将在当前模式中创建。 临时视图存在于一个特殊的模式里,所以创建临时视图的时候,不能给出模式名。 新视图名字必需和同一模式中任何其它视图、表、序列、索引或外部表的名字不同。

参数

TEMPORARYTEMP

如果声明了这个子句,那么视图就以临时视图的方式创建。 临时视图在当前会话结束的时候将被自动删除。当前会话中,在临时视图存在的期间, 将无法看到现有的同名关系,除非用模式修饰的名字引用它们。

如果视图引用的任何基础表是临时的,那么视图将被创建为临时的 (不管是否声明了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_

一个将为视图提供行和列的SELECTVALUES语句。

注意

使用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规则, 保持不变。要替换视图,你必须拥有该视图(包括成为拥有者角色的一员)。

可更新的视图

简单的视图是自动可更新的:系统允许INSERTUPDATEDELETE语句和在规则表上一样的方式在视图上使用。 如果视图满足所有下列的条件,那么就是自动可更新的:

  • 视图在它的FROM列表中必须只有一个条目, 该条目必须是一个表或其他可更新视图。

  • 视图定义必须没有在顶级包含WITHDISTINCTGROUP BYHAVINGLIMITOFFSET子句。

  • 视图定义必须没有在顶级包含集合运算(UNIONINTERSECTEXCEPT)。

  • 视图的选择列表中的所有字段必须简单的引用底层关系的字段。 它们不能是表达式、字面值或函数。也不能引用系统字段。

  • 在视图的选择列表中,底层关系的字段出现不能超过一次。

  • 视图必须没有security_barrier属性。

如果视图是自动可更新的,那么系统将转换视图上的任意INSERTUPDATEDELETE语句为相应的底层基本关系上的语句。

如果一个自动可更新的视图包含一个WHERE条件, 那么该条件约束基本关系的哪些行可以被视图上的UPDATEDELETE语句修改。不过,允许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

这个选项控制自动可更新视图的行为。给出时,对视图的INSERTUPDATE都要检查以确保新行满足视图定义的条件(也就是说, 新行应该可以通过视图看到)。如果没有通过检查,更新将被拒绝。 没有CHECK OPTION,允许对视图的INSERTUPDATE命令创建通过该视图不可见的行。 (后者的行为当前只有PostgreSQL提供。)

LOCAL

对这个视图进行完整性检查。

CASCADED

对此视图和任何相关视图进行完整性检查。在既没有声明CASCADED 也没有声明LOCAL时,假设为CASCADED

CREATE OR REPLACE VIEW是PostgreSQL 的扩展。临时视图的概念也是扩展。WITH子句也是一个扩展。

又见

ALTER VIEW, DROP VIEW, CREATE MATERIALIZED VIEW