9.3 9.4 9.5 9.6 10 11 12
阿里云PostgreSQL 问题报告 纠错本页面

CREATE VIEW

名称

CREATE VIEW -- 定义一个新视图

大纲

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

描述

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] [, ... ] )

该子句为视图指定选项参数;支持下列参数:

check_option (string)

这个参数可以是localcascaded,相当于声明了 WITH [ CASCADED | LOCAL ] CHECK OPTION(见下文)。 可以使用ALTER VIEW在现有的视图中改变这个选项。

security_barrier (string)

如果视图打算提供行级别的安全就应该使用这个选项。参阅 第 38.5 节获取全部信息。

query

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

WITH [ CASCADED | LOCAL ] CHECK OPTION

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

LOCAL

只对视图本身直接定义的条件检查新行。任何底层基础视图定义的条件都不检查 (除非它们也声明了CHECK OPTION)。

CASCADED

针对该视图和所有底层基础视图的条件检查新行。如果声明了CHECK OPTION, 并且没有声明LOCAL也没有声明CASCADED, 那么假设是CASCADED

RECURSIVE视图不能使用CHECK OPTION

请注意,只在可自动更新、并且没有INSTEAD OF触发器或INSTEAD 规则的视图上支持CHECK OPTION。如果一个可自动更新的视图定义在一个拥有 INSTEAD OF触发器的基础视图的上面,那么会使用LOCAL CHECK OPTION 检查可自动更新视图上的条件,但是不会检查带有INSTEAD OF 触发器的基础视图上的条件(级联的检查选项将不会级联到一个触发器可更新的视图, 并且任何直接定义在触发器可更新视图上的检查选项将被忽略)。 如果该视图或者任何它的基础关系有一个INSTEAD规则, 导致INSERTUPDATE命令重写, 那么所有检查选项都将在重写的查询中忽略,包括任何来自定义在INSTEAD 规则的关系上的可自动更新视图的检查。

注意

使用DROP VIEW语句删除视图。

请注意视图字段的名字和类型不一定是你们期望的那样。比如,

CREATE VIEW vista AS SELECT 'Hello World';

在两个方面很糟糕:字段名缺省是?column? 并且字段的数据类型缺省是unknown。 如果你想视图的结果是一个字符串文本,那么请像下面这样使用:

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

对视图引用的表的访问的权限由视图的所有者决定。在一些情况下, 这可用于提供安全但是限制访问底层表。不过,不是所有视图对于篡改都是安全的; 参阅第 38.5 节获取细节。 在视图里被调用的函数,被当作直接从使用视图的查询里调用它们看待。因此, 视图的用户必须有调用视图使用的所有函数的权限。

CREATE OR REPLACE VIEW用在一个现有的视图上时, 只改变了视图定义的SELECT规则。其他视图属性,包括所有权、权限和非SELECT规则, 保持不变。要替换视图,你必须拥有该视图(包括成为拥有者角色的一员)。

可更新的视图

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

一个可自动更新的视图可能包含可更新和不可更新字段的混合。 如果一个字段是一个对底层基础关系的可更新字段的简单引用,那么它是可更新的; 否则该字段是只读的,如果INSERTUPDATE 语句尝试给它赋值,则会引起一个错误。

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

如果一个自动可更新的视图包含一个WHERE条件, 那么该条件约束基本关系的哪些行可以被视图上的UPDATEDELETE语句修改。不过,允许UPDATE 更改一个行,使得它不再满足WHERE条件,并且因此不再通过视图可见。 相似的,INSERT命令也可以插入不满足WHERE 条件的基本关系行,并且因此对这个视图不可见。CHECK OPTION 可以用来阻止INSERTUPDATE命令创建该视图不可见的行。

如果一个可自动更新的视图标记为security_barrier, 那么所有视图的WHERE条件(和任何使用标记为 LEAKPROOF的操作符的条件)将总是在视图的用户添加任何条件之前评估。 参阅第 38.5 节获取全部信息。请注意, 由于这个原因,不是最终返回的行(因为它们不通过用户的WHERE条件) 最终可能仍然被锁。可以使用EXPLAIN查看哪个条件应用在了关系级别 (并且因此没有锁定行)。

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

请注意,用户在视图上执行插入、更新或删除必须在该视图上有相应的插入、 更新或删除的权限。此外,视图的所有者必须在底层基础关系上有相关的权限, 但是执行更新的用户不需要在底层基础关系上的任何权限 (参阅第 38.5 节)。

例子

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

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';

这个视图将支持INSERTUPDATEDELETE。 所有来自films表的字段都将被更新,而计算的字段 countryavg_rating将是只读的。

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

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

兼容性

CREATE OR REPLACE VIEWPostgreSQL 的扩展。临时视图的概念也是扩展。WITH ( ... )子句也是一个扩展。

又见

ALTER VIEW, DROP VIEW, CREATE MATERIALIZED VIEW
<
/BODY >