🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
# 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](#calibre_link-480) 获取全部细节。 `_query_` 一个将为视图提供行和列的[SELECT](#calibre_link-104) 或[VALUES](#calibre_link-106)语句。 ## 注意 使用[DROP VIEW](#calibre_link-481)语句删除视图。 请注意视图字段的名字和类型不一定是你们期望的那样。比如, ``` CREATE VIEW vista AS SELECT 'Hello World'; ``` 在两个方面很糟糕:字段名缺省是`?column?` 并且字段的数据类型缺省是`unknown`。 如果你想视图的结果是一个字符串文本,那么请像下面这样使用: ``` CREATE VIEW vista AS SELECT text 'Hello World' AS hello; ``` 对视图引用的表的访问的权限由视图的所有者决定。在一些情况下, 这可用于提供安全但是限制访问底层表。不过,不是所有视图对于篡改都是安全的; 参阅[Section 38.5](#calibre_link-480)获取细节。 在视图里调用的函数当作他们直接从使用视图的查询里调用看待。因此, 视图的用户必须有调用视图使用的所有函数的权限。 当`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](#calibre_link-459)。还有一种可能性是创建规则 (参阅[CREATE RULE](#calibre_link-12)),但是实际上触发器更容易理解和正确使用。 请注意,用户在视图上执行插入、更新或删除必须在该视图上有相应的插入、 更新或删除的权限。此外,视图的所有者必须在底层基础关系上有相关的权限, 但是执行更新的用户不需要在底层基础关系上的任何权限 (参阅[Section 38.5](#calibre_link-480))。 ## 例子 创建一个由所有喜剧电影组成的视图: ``` 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](#calibre_link-482), [DROP VIEW](#calibre_link-481), [CREATE MATERIALIZED VIEW](#calibre_link-109)