CREATE VIEW

创建视图-定义新视图

Synopsis

CREATE [ OR REPLACE ] [ TEMP | TEMPORARY ] [ RECURSIVE ] VIEW name [ ( column_name [, ...] ) ]
    [ WITH ( view_option_name [= view_option_value] [, ... ] ) ]
    AS query
    [ WITH [ CASCADED | LOCAL ] CHECK OPTION ]

Description

CREATE VIEW定义查询视图。该视图未在实体上实现。而是,每次在查询中引用视图时都运行查询。

CREATE OR REPLACE VIEW类似,但是如果已经存在相同名称的视图,则将其替换。新查询必须生成与现有视图查询生成的列相同的列(即,相同的列名以相同的 Sequences 和相同的数据类型),但是它可能会将其他列添加到列表的末尾。产生输出列的计算可能完全不同。

如果指定了架构名称(例如CREATE VIEW myschema.myview ...),则将在指定的架构中创建视图。否则,它将在当前架构中创建。临时视图存在于特殊的架构中,因此在创建临时视图时无法给出架构名称。视图的名称必须与同一架构中的任何其他视图,表,序列,索引或外部表的名称不同。

Parameters

  • TEMPORARYTEMP

    • 如果指定,则将视图创建为临时视图。临时视图会在当前会话结束时自动删除。具有临时名称的现有永久关系在临时视图存在时在当前会话中不可见,除非使用架构限定名称来引用它们。

如果该视图引用的任何表都是临时表,则该视图将被创建为临时视图(是否指定TEMPORARY)。

  • RECURSIVE

    • 创建一个递归视图。语法
CREATE RECURSIVE VIEW [ schema . ] view_name (column_names) AS SELECT ...;

相当于

CREATE VIEW [ schema . ] view_name AS WITH RECURSIVE view_name (column_names) AS (SELECT ...) SELECT column_names FROM view_name;

必须为递归视图指定视图列名称列表。

  • name

    • 要创建的视图的名称(可选的模式限定)。
  • column_name

    • 用于视图列的名称的可选列表。如果未给出,则从查询中推导出列名。
  • WITH ( view_option_name [= view_option_value] [, ... ] )

    • 此子句指定视图的可选参数;支持以下参数:
  • check_option ( string )

    • 该参数可以是localcascaded,等效于指定WITH [ CASCADED | LOCAL ] CHECK OPTION(请参见下文)。可以使用ALTER VIEW在现有视图上更改此选项。

    • security_barrier ( boolean )

      • 如果该视图旨在提供行级安全性,则应使用此方法。有关完整详细信息,请参见Section 40.5
  • query

  • WITH [ CASCADED | LOCAL ] CHECK OPTION

    • 此选项控制自动更新视图的行为。指定此选项后,将检查视图上的INSERTUPDATE命令以确保新行满足视图定义条件(即,检查新行以确保它们在视图中可见)。如果不是,则更新将被拒绝。如果未指定CHECK OPTION,则允许视图上的INSERTUPDATE命令创建在视图中不可见的行。支持以下检查选项:
  • LOCAL

    • 仅对照直接在视图本身中定义的条件检查新行。不会检查在基础基本视图上定义的任何条件(除非它们也指定CHECK OPTION)。

    • CASCADED

      • 将根据视图和所有基础视图的条件检查新行。如果指定了CHECK OPTION,而未指定LOCALCASCADED,则假定为CASCADED

CHECK OPTION不能与RECURSIVE视图一起使用。

请注意,只有可自动更新且没有INSTEAD OF触发器或INSTEAD规则的视图才支持CHECK OPTION。如果在具有INSTEAD OF触发器的基本视图之上定义了自动更新视图,则LOCAL CHECK OPTION可用于检查自动更新视图上的条件,但不会检查具有INSTEAD OF触发器的基本视图上的条件(a 层叠检查选项不会层叠到触发可更新视图,并且直接在触发可更新视图上定义的任何检查选项都将被忽略)。如果视图或其任何基本关系具有导致INSERTUPDATE命令被重写的INSTEAD规则,则在重写的查询中所有检查选项将被忽略,包括在关系顶部定义的自动更新视图中的所有检查。 INSTEAD规则。

Notes

使用DROP VIEW语句删除视图。

请注意,视图列的名称和类型将按照您想要的方式进行分配。例如:

CREATE VIEW vista AS SELECT 'Hello World';

格式错误,因为列名称默认为?column?;同样,列数据类型默认为text,这可能不是您想要的。视图结果中的字符串 Literals 的更好样式是:

CREATE VIEW vista AS SELECT text 'Hello World' AS hello;

对视图中引用的表的访问由视图所有者的权限决定。在某些情况下,这可用于提供对基础表的安全但受限制的访问。但是,并非所有视图都可以防止篡改。有关详情,请参见Section 40.5。在视图中调用的函数的处理方式与使用视图直接从查询中调用它们的方式相同。因此,视图的用户必须有权调用该视图使用的所有功能。

在现有视图上使用CREATE OR REPLACE VIEW时,仅更改视图的定义 SELECT 规则。其他视图属性(包括所有权,权限和非 SELECT 规则)保持不变。您必须拥有视图才能替换它(包括成为拥有角色的成员)。

Updatable Views

简单视图可以自动更新:系统将允许INSERTUPDATEDELETE语句以与常规表相同的方式在视图上使用。满足以下所有条件的视图将自动更新:

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

  • 视图定义不得在顶层包含WITHDISTINCTGROUP BYHAVINGLIMITOFFSET子句。

  • 视图定义不得在顶层包含设置操作(UNIONINTERSECTEXCEPT)。

  • 视图的选择列表不得包含任何集合,窗口函数或返回集合的函数。

可自动更新的视图可能包含可更新列和不可更新列的混合。如果列是对基础基础关系的可更新列的简单引用,则该列是可更新的;否则,该列为只读,并且如果INSERTUPDATE语句尝试为其分配值,则会引发错误。

如果视图可以自动更新,则系统会将视图上的任何INSERTUPDATEDELETE语句转换为基础基本关系上的相应语句。完全支持具有ON CONFLICT UPDATE子句的INSERT语句。

如果自动可更新的视图包含WHERE条件,则该条件将限制可通过视图上的UPDATEDELETE语句修改基本关系的哪些行。但是,允许UPDATE更改行,使其不再满足WHERE条件,因此在视图中不再可见。类似地,INSERT命令可能会插入不满足WHERE条件的基本关系行,因此在视图中不可见(ON CONFLICT UPDATE类似地会影响在视图中不可见的现有行)。 CHECK OPTION可用于防止INSERTUPDATE命令创建在视图中不可见的行。

如果使用security_barrier属性标记了可自动更新的视图,则将始终在添加视图用户的任何条件之前评估所有视图的WHERE条件(以及使用标记为LEAKPROOF的运算符的任何条件)。有关完整详细信息,请参见Section 40.5。请注意,由于这个原因,最终没有返回的行(因为它们没有通过用户的WHERE条件)可能仍然会被锁定。 EXPLAIN可用于查看在关系级别应用了哪些条件(因此不锁定行),哪些没有应用。

不满足所有这些条件的更复杂的视图默认情况下为只读:系统将不允许在该视图上进行插入,更新或删除。您可以通过在视图上创建INSTEAD OF触发器来获得可更新视图的效果,该触发器必须将视图上尝试插入的内容等转换为对其他表的适当操作。有关更多信息,请参见CREATE TRIGGER。另一种可能性是创建规则(请参阅CREATE RULE),但实际上触发器易于理解和正确使用。

请注意,在视图上执行插入,更新或删除的用户必须在视图上具有相应的插入,更新或删除特权。另外,视图的所有者必须对基础基本关系具有相关的特权,但是执行更新的用户不需要对基础基本关系的任何许可(请参见Section 40.5)。

Examples

创建一个由所有喜剧电影组成的视图:

CREATE VIEW comedies AS
    SELECT *
    FROM films
    WHERE kind = 'Comedy';

这将创建一个视图,其中包含创建视图时film表中的列。尽管使用*来创建视图,但是稍后添加到表中的列将不属于视图。

使用LOCAL CHECK OPTION创建视图:

CREATE VIEW universal_comedies AS
    SELECT *
    FROM comedies
    WHERE classification = 'U'
    WITH LOCAL CHECK OPTION;

这将基于comedies视图创建一个视图,仅显示具有kind = 'Comedy'classification = 'U'的电影。如果新行不具有classification = 'U',则对视图中的INSERTUPDATE行的任何尝试都将被拒绝,但是影片kind不会被检查。

使用CASCADED CHECK OPTION创建视图:

CREATE VIEW pg_comedies AS
    SELECT *
    FROM comedies
    WHERE classification = 'PG'
    WITH CASCADED CHECK OPTION;

这将创建一个检查新行的kindclassification的视图。

创建包含可更新列和不可更新列的混合视图:

CREATE VIEW comedies AS
    SELECT f.*,
           country_code_to_name(f.country_code) AS country,
           (SELECT avg(r.rating)
            FROM user_ratings r
            WHERE r.film_id = f.id) AS avg_rating
    FROM films f
    WHERE f.kind = 'Comedy';

此视图将支持INSERTUPDATEDELETEfilms表中的所有列都是可更新的,而计算出的列countryavg_rating将是只读的。

创建一个由 1 到 100 的数字组成的递归视图:

CREATE RECURSIVE VIEW public.nums_1_100 (n) AS
    VALUES (1)
UNION ALL
    SELECT n+1 FROM nums_1_100 WHERE n < 100;

请注意,尽管在此CREATE中递归视图的名称是架构限定的,但其内部自引用不是架构限定的。这是因为隐式创建的 CTE 名称不能被模式限定。

Compatibility

CREATE OR REPLACE VIEW是 PostgreSQL 语言扩展。临时视图的概念也是如此。 WITH ( ... )子句也是一个扩展。

See Also

ALTER VIEW, DROP VIEW, 创建材料视图