选择 打开 改范围 完整检索页

pgsql.cc 提供对 postgresql.org 官网内容的中文翻译,由 Pigsty 团队维护。

受支持版本: 当前版本 (18) / 17 / 16 / 15 / 14
测试与开发版本: 19 / devel
不受支持的版本: 13 / 12 / 11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2 / 9.1 / 9.0
历史版本PostgreSQL 9.3 已于 2018 年 11 月结束社区维护,本页译文保留供仍在使用旧版本的读者参考。新系统请看当前版本

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

该子句为视图指定可选参数;目前唯一支持的参数名是security_barrier,如果视图旨在提供行级安全,则应启用该选项。完整细节请参见第 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;

对视图中引用的表的访问由视图所有者的权限决定。在某些情况下,这可以用于为底层表提供安全但受限的访问。不过,并非所有视图都能防止篡改;详情请参见第 38.5 节。视图调用的函数与直接从使用该视图的查询中调用时的处理方式相同。因此,视图的用户必须拥有调用视图所用全部函数的权限。

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

可更新视图

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

  • 在该视图的FROM列表中必须刚好只有一个项,并且该项必须是一个表或另一个可更新视图。

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

  • 视图定义中不能包含集合操作(UNIONINTERSECTEXCEPT)。

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

  • 被引用关系的任何列都不能在 SELECT 列表中出现超过一次。

  • 该视图不能带有security_barrier属性。

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

如果自动可更新视图包含WHERE条件,该条件将限制底层关系中哪些行可以被视图上的UPDATEDELETE语句修改。但是,UPDATE允许把某行修改为不再满足WHERE条件、因而不再通过视图可见。类似地,INSERT命令有可能插入不满足WHERE条件、因而不通过视图可见的底层关系行。

不满足所有这些条件的更复杂视图默认是只读的:系统不允许在该视图上执行插入、更新或删除。可以通过在视图上创建INSTEAD OF触发器来获得可更新视图的效果,这些触发器必须把对视图的插入等尝试转换为对其他表的适当动作。更多信息见CREATE TRIGGER。另一种可能的做法是创建规则(见CREATE RULE),但在实践中触发器更容易理解并且更容易正确使用。

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

示例

创建一个包含所有喜剧电影的视图:

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

该视图将包含视图创建时位于film表中的列。尽管使用了*创建视图,但以后添加到表中的列不会成为视图的一部分。

创建一个由 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 名称不能使用模式限定名。

兼容性

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 VIEWPostgreSQL的语言扩展。临时视图的概念也是如此。WITH子句同样是扩展。

提交更正

译文有误、术语不当或页面显示问题,请到译文仓库 pgsty/pgdoc 报告译文问题。 英文原文本身的问题,请在当前版本的对应页面向上游反馈;上游不再修订已结束维护的版本。