UpdatableView

From PostgreSQL 中文维基, PostgreSQL 中文站, PostgreSQL 中国社区, PostgreSQL Chinese community

Jump to: navigation, search

目录

[编辑] 可更新视图初步介绍(未完,待续)

[编辑] 1.视图

1 *_Database System Concepts_* (Fourth Edition)

Abraham Silberschatz, Henry F. Korth,S.Sudarshan

3.5节中给出的视图概念是: 任意一个不是逻辑模型的一部分,但是却作为一个虚表对用户可见的关系,称之为视图。 (Any relation that is not part of the logical model, but is made visible to a user as a virtual relation, is called a view.)


2 引用: from http://zedware.org/db/db-updateble-views.html

视图是从一个或多个基表(或视图)导出的表。通常视图仅仅是一个虚表,即数据库中只存放视图的定义信息等元数据,而不存放视图对应的数据。 视图上的操作和基表类似,但是 DBMS对视图的更新操作(INSERT、DELETE、UPDATE)往往存在一定的限制。 DBMS对视图进行的权限管理和基表也有所不同。      视图可以提高数据的逻辑独立性,也可以增加一定的安全性。 DBMS在处理视图时和基表存在很多不同的地方,例如:

定义:基于基表或视图 数据:一般不单独存放 查询:允许,和基表类似 插入:有限制 删除:有限制 更新:有限制 权限:有所不同


  本文主要讨论视图的可更新性,即考虑视图上的更新类操作存在哪些特点和限制。

[编辑] 2.可更新视图

[编辑] 2.1 可更新视图的定义

para1

   顾名思义,可更新视图是指可以执行更新操作的视图。
   
   在本文中,可更新视图指:....
   
   定义

para2

   flying:个人理解的基本原则是: 视图中的行列,要能够和基表中的行列一一对应。

[编辑] 2.2 SQL标准对可更新视图的支持

[编辑] 2.2.1 视图本身的可更新性支持

个人理解: CREATE VIEW语句中的 WITH [ CASCADED | LOCAL ] CHECK OPTION 都针对的可更新视图,因此理解为:视图创建语法中支持 WITH [ CASCADED | LOCAL ] CHECK OPTION 的SQL语言,其实现的视图 是可更新视图;否则为只读视图。

下面是摘自 http://www.pgsqldb.org/pgsqldoc-8.1c/sql-createview.html 的一段话:

{ flying: 不确定是哪个版本的标准 SQL 标准为 CREATE VIEW 声明了一些附加的功能:

CREATE VIEW name [ ( column_name [, ...] ) ]

   AS query
   [ WITH [ CASCADED | LOCAL ] CHECK OPTION ]

完整的SQL命令可选的子句是:


CHECK OPTION 这个选项用于可更新视图。 所有对视图的INSERT和UPDATE都要经过视图定义条件的校验。 (也就是说,新数据应该可以通过视图看到。)如果没有通过校验,更新将被拒绝。

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

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

}


[编辑] 2.1.2 SQL-92

(1)原文节选:

 11.19<view definition> 

  Function

         Define a viewed table.

         Format

         <view definition> ::=
              CREATE VIEW <table name> [ <left paren> <view column list>
              <right paren> ]
                AS <query expression>
                [ WITH [ <levels clause> ] CHECK OPTION ]

         <levels clause> ::=
              CASCADED | LOCAL

         <view column list> ::= <column name list>


         Syntax Rules

         1) The <query expression> shall not contain a <target specifica-
            tion> or a <dynamic parameter specification>.

         2) If a <view definition> is contained in a <schema definition>
            and the <table name> contains a <schema name>, then that <schema
            name> shall be the same as the specified or implicit <schema
            name> of the containing <schema definition>.

         .....

         6) If the <query expression> is updatable, then the viewed table is
            an updatable table. Otherwise, it is a read-only table.

         ......

         12)If WITH CHECK OPTION is specified, then the viewed table shall
            be updatable.

         13)If WITH CHECK OPTION is specified with no <levels clause>, then
            a <levels clause> of CASCADED is implicit.

         14)Let V be the view defined by the <view definition>. The un-
            derlying columns of every i-th column of V are the underlying
            columns of the i-th column of the <query expression> and the
            underlying columns of V are the underlying columns of the <query
            expression>.

         Access Rules

         1) If a <view definition> is contained in a <module>, then the
            current <authorization identifier> shall be equal to the <au-
            thorization identifier> that owns the schema identified by the
            implicit or explicit <schema name> of the <table name>.

         General Rules

         1) A view descriptor VD is created that describes V. The view de-
            scriptor includes the <table name>, the <query expression>,
            column descriptors taken from the table specified by the <query
            expression>, and an indication of whether WITH CHECK OPTION was
            specified. If a <view column list> is specified, then the <col-
            umn name> of the i-th column of the view is the i-th <column
            name> in that <view column list>. Otherwise, the <column name>s
            of the view are the <column name>s of the table specified by the
            <query expression>.

         2) Let VN be the <table name>. Let QE be the <query expression>.
            If a <view column list> is specified, then let VCL be the <view
            column list> preceded by a <left paren> and followed by a <right
            paren>; otherwise, let VCL be the empty string.

            Case:

            a) When VN is immediately contained in some SQL-schema state-
              ment, it identifies the view descriptor VD.
          b) Otherwise, VN references the same table as the <table refer-
              ence>:

                 ( QE ) AS VN VCL

         3) Let A be the <authorization identifier> that owns V.

         4) A set of privilege descriptors is created that defines the priv-
            ilege SELECT on this table to A and SELECT for each column of
            V to A. This privilege is grantable if and only if the appli-
            cable SELECT privileges on all <table name>s contained in the
            <query expression> are grantable. The grantor of this privilege
            descriptor is set to the special grantor value "_SYSTEM".

         5) If V is updatable, then let T be the leaf underlying table of
            the <query expression>.

         6) For i ranging from 1 to the number of distinct leaf underlying
            tables of the <query expression> of V, let RTi be the <table
            name>s of those tables. For every column CV of V:

            a) Let CRij, for j ranging from 1 to the number of columns of
              RTi that are underlying columns of CV, be the <column name>s
              of those columns.

            b) If A has REFERENCES(CRij) for all i and for all j, and A has
              REFERENCES on some column of RTi for all i, then a privilege
              descriptor is created that defines the privilege REFERENCES
              (CV) on V to A. That privilege is grantable if and only if
              the REFERENCES privileges on all of the columns CRTij are
              grantable. The grantor of that privilege descriptor is set to
              the special grantor value "_SYSTEM".

         7) If V is updatable, then:

            a) A set of privilege descriptors is created that defines the
              privileges INSERT, UPDATE, and DELETE on V that are appli-
              cable privileges on T to A. A privilege on V is grantable if
              and only if the corresponding privilege on T is grantable.

            b) For every column in V:

              i) There is a corresponding column in T from which the column
                 of V is derived. Let CV and CT be the <column name>s of the
                 corresponding columns of V and T respectively.

             ii) A set of privilege descriptors is created that defines
                 the privileges INSERT(CV) and UPDATE(CV) on V, where the
                 privileges INSERT(CT) and UPDATE(CT) on T are the appli-
                 cable privileges to A, respectively. A privilege on V is
                 grantable if and only if the corresponding privilege on T
                 is grantable.

              The grantor of these privilege descriptors is set to the
              special grantor value "_SYSTEM".
         8) If V is updatable, then let TLEAF be the leaf generally under-
            lying table of V. For every row in V there is a corresponding
            row in TLEAF from which the row of V is derived and for each
            column in V there is a corresponding column in TLEAF from which
            the column of V is derived. The insertion of a row into V is
            an insertion of a corresponding row into TLEAF. The deletion of
            a row from V is a deletion of the corresponding row in TLEAF.
            The updating of a column of a row in V is an updating of the
            corresponding column of the corresponding row in TLEAF.

         9) Let V1 be a view. V1 spans V1. V1 spans a view V2 if V2 is a
            generally underlying table of V1.

         10)An update operation is an <insert statement>, <update state-
            ment: positioned>, <update statement: searched>, <dynamic update
            statement: positioned>, or <preparable dynamic update state-
            ment: positioned>. An update operation on a view V is an update
            operation whose <table name> identifies V.

         11)If a view V1 spans a view VA described by a view descriptor that
            includes WITH CHECK OPTION and an update operation on V1 would
            result in a row that would not appear in the result of VA, then

            a) If the view descriptor of VA includes CASCADED, then an ex-
              ception condition is raised: with check option violation.

            b) If the view descriptor of VA includes LOCAL and the update
              operation would result in a row that would appear in the
              simply underlying table of the simply underlying table of
              the <query expression> contained in VA, then an exception
              condition is raised: with check option violation.

         12)Validation of a WITH CHECK OPTION constraint is effectively
            performed at the end of each update operation.

         13)If the character representation of the <query expression> cannot
            be represented in the Information Schema without truncation,
            then a completion condition is raised: warning-query expression
            too long for information schema.

         Leveling Rules

         1) The following restrictions apply for Intermediate SQL:

            a) Conforming Intermediate SQL language shall not contain any
              <levels clause>, but the effect shall be that defined for a
              <levels clause> of CASCADED.

         2) The following restrictions apply for Entry SQL in addition to
            any Intermediate SQL restrictions:

            a) The <query expression> in a <view definition> shall be a
              <query specification>.

(2) 译文

翻译,by flying,有错误请指出。

 11.19<视图定义> 

  功能

         定义一个视图。

   格式

         <view definition> ::=
              CREATE VIEW <table name> [ <left paren> <view column list>
              <right paren> ]
                AS <query expression>
                [ WITH [ <levels clause> ] CHECK OPTION ]

         <levels clause> ::=
              CASCADED | LOCAL

         <view column list> ::= <column name list>


    语法规则

         1)  <query expression> 不能包含 <target specification> 或
         <dynamic parameter specification>.

         2) 如果 <view definition> 包含在一个 <schema definition>中,并且
             <table name> 一项中包含 <schema name>,则在 <table name> 中
        <schema name> 明确指定的或者隐含的 <schema name>应该与
        <schema definition>中的相同.

       ......

         6) 如果 <query expression> 是可更新的, 那么 the viewed table 就是
    可更新的表. 否则,它就是个只读的表.

    (flying 译者注:<query expression> 的可更新性同样在标准中规定了,
     请参阅原文,此处不再翻译)

        ......

         12)如果指定了 WITH CHECK OPTION , 那么这个视图是可更新的.

         13)如果 WITH CHECK OPTION 没有指定 <levels clause>, 那么
            CASCADED是默认值.

         14)令 V 是一个通过 <view definition>定义的视图. V中隐含的列就是
       <query expression> 中隐含的列。
           

         存取规则

         1) 如果 <view definition>包含在 <module>中,那么当前的
            <authorization identifier>应该与拥有<table name>中明确或隐含
       指出的<schema name>模式的<authorization identifier>相同。


         一般规则

         1) 视图描述符 VD被创建用来描述 V. 视图描述符包括 <table name>, 
       <query expression>,<query expression>中指定的表给出的列描述符 
            , 以及是否 指出WITH CHECK OPTION 的指示. 如果 明确指出了
       <view column list>,那么 视图中i个列的<column name>就是<view 
       column list> 中的<column name>. 否则,视图的 <column name>
            就是 <query expression>涉及到的表中的列名 .

         2) 令VN 表示 <table name>. 令 QE 表示 <query expression>.
            如果指定了 <view column list>, 那么令VCL 表示 <view
            column list> 并且其以<left paren>开头, 后面紧跟<right paren>; 
       否则, 另 VCL 是空字符串.

            情形:

            a) 当VN 直接地被包含在某个 SQL-模式 声明中, 它被识别为 视图描述符 VD.
            b) 否则, VN 参考 <table reference>中的同一个表:

                 ( QE ) AS VN VCL

         3) 令A表示V拥有的 <authorization identifier>.

    4) 被创建的一组权限描述符定义A包含了对表的SELECT权限,  并且
        包含对V中每个列的SELECT权限. 当且仅当可应用的SELECT权限
        在<query expression>中包括的所有表名上都是可授权的(grantable),
        那么这个 权限就是可授权的(grantable).权限描述符的授予者被设置
        成一个特殊的值"_SYSTEM".

         5) 如果 V 是可更新的, 那么令T表示<query expression>中的基础叶子表
        ( leaf underlying table) .

         6) 对 i 从1变化到V的<query expression>中的不同基础叶子表的数量, 
         则令 RTi 表示那些表的表名字. 对V中的每一个列CV:

            a)令CRij表示CV的每一个基础列的列名字<column name>, 其中
          j的范围是从1 到 CV涉及到的RTi中的列的数量.

            b)如果 A 有 REFERENCES(CRij) 对所有的 i 和所有的 j, 并且 A对
          有 RTi的所有i值的同一列有REFERENCES 权限, 那么一个定义
           对V的REFERENCES(CV) 权限描述符将被创建到A. 当且仅当
       所有CRTij列的REFERENCES权限是可授权的,则这个权限可
       授权. 这个权限描述符的授予者,被设置为一个特殊的值 "_SYSTEM".

         7) 如果V 是可更新的, 那么:

            a) 一系列的权限描述符被创建到A,定义了对V的INSERT, UPDATE, 和 
           DELETE 权限,这些权限是对T的可用权限. 当且仅当相关的对T的权限
      是可授权的,则V上的该权限是可授权的.

            b) 对 V中的每个列:

              i) 有一个相对应的T中的列,其中V中的列抽取来自T.令 CV和CT分别表示
             V和T中的相应列的列名字 <column name>.

             ii) 一个权限描述符集被创建到A,他定义了 对V的INSERT(CV) 和 UPDATE(CV)
               , 这里对T的 INSERT(CT) 和 UPDATE(CT) 权限分别都是可用的.当且仅当相应
          的对T的权限是可授权的,  对 V 的权限才可授权。
            
              这些权限的授予者被设置为一个特殊的值 "_SYSTEM".

         8)如果V是可更新的, 那么令 TLEAF 表示V中的普通叶子基表( leaf generally 
        underlying table) of V. 对V中的每一行都存在一个TLEAF中的对应行,V中的
        行源自那行,并且对V中的每一列都存在一个TLEAF对应的列,其中V中的每
        一列都源自那. 向V插入一行的操作就是对 TLEAF插入相应一行. 从V中删除
        一行就是从TLEAF中删除相应一行. 对V中一行上某一列的更新就是对TLEAF
        中相应行上的相应列的更新.
        

         9) 令V1表示一个视图. V1 spans V1. V1 spans a view V2 if V2 is a
            generally underlying table of V1.

         10)一个更新操作是 <insert statement>, <update state-
            ment: positioned>, <update statement: searched>, <dynamic update
            statement: positioned>, 或 <preparable dynamic update state-
            ment: positioned>. 一个对视图的更新操作是一个更新操作, 这个操作的
       <table name>标识是V.

         11)如果视图 V1 扩展(spans) 出了视图 VA , 其中VA被一个视图描述符
       描述,该描述符包括WITH CHECK OPTION, 并且对V1的 update 操作
       会导致一个不会出现在VA结果中的一行, 那么

            a) 如果VA的视图描述符包括CASCADED , 那么将发出一个异常条件: 
           with check option violation.

            b) 如果VA的视图描述符包括LOCAL , 那么update操作将导致这一行出现
         在VA的<query expression>中的简单下层表的简单下层表中( the
              simply underlying table of the simply underlying table of
              the <query expression> contained in VA), 然后发出一个异常条件: 
            with check option violation.

         12)WITH CHECK OPTION 约束的确认在每个update操作后被有效的执行.

         13)如果<query expression>中的字符表示, 不能不被切断的表示为信息模式,
            那么发出一个完成条件: warning-query expression too long for information schema.

        基准准则

         1) 下面的限制应用于中级的SQL(Intermediate SQL):

            a) 一致的中级SQL(Conforming Intermediate SQL language)语言,
          不应该包含任何<levels clause>,但是其效果应该是<levels clause>
          被定义为  CASCADED的.

         2) 除了中级SQL的限制外, 下面的限制应用于入门级的SQL:

            a) <view definition>中的 <query expression>应该是一个 <query specification>.
[编辑] 2.2.3 SQL-99

(1) 原文节选

来源: SQL99, ANSI/ISO/IEC 9075-2:1999

11.21  <view definition>

Function
   Define a viewed table.

Format

<view definition> ::=
   CREATE [ RECURSIVE ] VIEW <table name>
   <view specification>
   AS <query expression>
   [ WITH [ <levels clause> ] CHECK OPTION ]

<view specification> ::=
   <regular view specification>
   | <referenceable view specification>

<regular view specification> ::=
   [ <left paren> <view column list> <right paren> ]

<referenceable view specification> ::=
   OF <user-defined type>
   [ <subview clause> ]
   [ <view element list> ]


<subview clause> ::= UNDER <table name>

<view element list> ::=
   <left paren>
      [ <self-referencing column specification> <comma> ]
      <view element> [ { <comma> <view element> }... ]
   <right paren>

<view element> ::= <view column option>

<view column option> ::= <column name> WITH OPTIONS <scope clause>

<levels clause> ::=
   CASCADED
   | LOCAL

<view column list> ::= <column name list>


Syntax Rules
......

9) The viewed table is updatable if and only if the <query expression> is updatable.

10) The viewed table is insertable-into if and only if the <query expression> is insertable-into.
......
16) If WITH CHECK OPTION is specified, then the viewed table shall be updatable.

17) If WITH CHECK OPTION is specified and <levels clause> is not specified, then a <levels
      clause> of CASCADED is implicit.

18) If WITH LOCAL CHECK OPTION is specified, then the <query expression> shall not generally
      contain a <query expression> QE or a <query specification> QS that is possibly nondeterministic
      unless QE or QS is generally contained in a viewed table that is a leaf underlying
      table of the <query expression>.
      If WITH CASCADED CHECK OPTION is specified, then the <query expression> shall not generally
      contain a <query expression> or <query specification> that is possibly non-deterministic.
.......
23) A column of V is called an updatable column of V if its underlying column is updatable.

(2) 译文

翻译,by flying,有错误请指出。

11.21<视图定义> 

  功能

         定义一个视图。

   格式

<view definition> ::=
   CREATE [ RECURSIVE ] VIEW <table name>
   <view specification>
   AS <query expression>
   [ WITH [ <levels clause> ] CHECK OPTION ]

<view specification> ::=
   <regular view specification>
   | <referenceable view specification>

<regular view specification> ::=
   [ <left paren> <view column list> <right paren> ]

<referenceable view specification> ::=
   OF <user-defined type>
   [ <subview clause> ]
   [ <view element list> ]


<subview clause> ::= UNDER <table name>

<view element list> ::=
   <left paren>
      [ <self-referencing column specification> <comma> ]
      <view element> [ { <comma> <view element> }... ]
   <right paren>

<view element> ::= <view column option>

<view column option> ::= <column name> WITH OPTIONS <scope clause>

<levels clause> ::=
   CASCADED
   | LOCAL

<view column list> ::= <column name list>

语法规则
......

9) 当且仅当<query expression> 是可更新的, 可视的表(a viewed table)才是可更新的.

(flying 译者注:<query expression> 的可更新性同样在标准中规定了,
     请参阅原文,此处不再翻译)

10) 当且仅当<query expression> 是可插入的, 可视的表才是可插入的.

(flying 译者注:<query expression> 的可插入性同样在标准中规定了,
     请参阅原文,此处不再翻译)
......
16) 如果指明了WITH CHECK OPTION ,那么可视的表是可更新的.

17) 如果指明了 WITH CHECK OPTION 但是没有指出 <levels clause>
       那么CASCADED是默认值.

18) 如果明确使用了WITH LOCAL CHECK OPTION, 那么
   <query expression> 不能泛泛地包含 <query expression> QE
   或 <query specification> QS ,它们可能是不确定的,除非QE 
   或 QS 通常的包括在一个可视的表中,那个表是<query expression>
   中的一个叶子下层表(leaf underlying table)  .
        如果明确使用了WITH CASCADED CHECK OPTION , 那么
   <query expression> 不能泛泛地包括 <query expression> 或
   <query specification> ,它们可能是不确定的,
.......
23)  如果V(表示一个视图)中的一个列其下层的列是可更新的,
       那么V中这个列就是可更新的.
.......

[编辑] 2.2.4 SQL-2003(草稿)

(1)原文节选

<view definition>

Function

   Define a viewed table.

Format

<view definition> ::=
   CREATE [ RECURSIVE ] VIEW <table name> <view specification>
   AS <query expression> [ WITH [ <levels clause> ] CHECK OPTION ]

<view specification> ::=
   <regular view specification>
   | <referenceable view specification>

<regular view specification> ::=
   [ <left paren> <view column list> <right paren> ]

<referenceable view specification> ::=
   OF <path-resolved user-defined type name> [ <subview clause> ]
   [ <view element list> ]

<subview clause> ::= UNDER <table name>

<view element list> ::=
   <left paren> <view element> [ { <comma> <view element> }... ] <right paren>
      <view element> ::=
      <self-referencing column specification>
      | <view column option>
      
<view column option> ::= <column name> WITH OPTIONS <scope clause>

<levels clause> ::=
   CASCADED
   | LOCAL

<view column list> ::= <column name list>
   
   
   Syntax Rules
......
9) The viewed table is updatable if the <query expression> is updatable.

10) The viewed table is simply updatable if the <query expression> is simply updatable.

11) The viewed table is effectively updatable if it is simply updatable, or if the SQL implementation supports
       Feature T111, “Updatable joins, unions, and columns”, and the viewed table is updatable.

12) The viewed table is insertable-into if the <query expression> is insertable-into.
......
18) If WITH CHECK OPTION is specified, then the viewed table shall be updatable.

19) If WITH CHECK OPTION is specified and <levels clause> is not specified, then a <levels clause> of
      CASCADED is implicit.
......
25) A column of V is called an updatable column of V if its underlying column is updatable.
......

General Rules

1) A view descriptor VD is created that describes V. VD includes:

   a) The <table name> TN.
   b) QE, as both the <query expression> of the descriptor and the original <query expression> of the
           descriptor.
        c) case :  
       ......
   d) In each column descriptor, an indication that the column is updatable if V is effectively updatable, and
             the corresponding column of QE is updatable.   
......        

(2)译文

翻译,by flying,有错误请指出。

<view definition>

功能

   Define a viewed table.

格式

<view definition> ::=
   CREATE [ RECURSIVE ] VIEW <table name> <view specification>
   AS <query expression> [ WITH [ <levels clause> ] CHECK OPTION ]

<view specification> ::=
   <regular view specification>
   | <referenceable view specification>

<regular view specification> ::=
   [ <left paren> <view column list> <right paren> ]

<referenceable view specification> ::=
   OF <path-resolved user-defined type name> [ <subview clause> ]
   [ <view element list> ]

<subview clause> ::= UNDER <table name>

<view element list> ::=
   <left paren> <view element> [ { <comma> <view element> }... ] <right paren>
      <view element> ::=
      <self-referencing column specification>
      | <view column option>
      
<view column option> ::= <column name> WITH OPTIONS <scope clause>

<levels clause> ::=
   CASCADED
   | LOCAL

<view column list> ::= <column name list>
   
   
   语法规则
......
9) 当且仅当<query expression> 是可更新的, 可视的表(a viewed table)才是可更新的.

10) 当且仅当<query expression> 是完全可更新的(simply updatable), 
      可视的表(a viewed table)才是可完全更新的(simply updatable).

11) 可视的表是有效可更新的, 如果它是完全可更新的(simply updatable),  或者如果
       SQL实现支持特征 T111, “可更新的join, union, and 列”, 并且可视的表是可更新的.

12) 当且仅当<query expression> 是可插入的, 可视的表(a viewed table)才是可插入的.
......
18) 如果指明了WITH CHECK OPTION ,那么可视的表是可更新的.

19) 如果指明了 WITH CHECK OPTION 但是没有指出 <levels clause>
       那么CASCADED是默认值.
......
25) 如果V(代表一个视图,译者注)中的一个列的下层列是可更新的被称
      为可更新列.
......

General Rules
1) 一个视图描述符 VD 被创建用于描述视图 V. VD包含:

   a) 表名称 <table name> TN.
   b) QE, as both the <query expression> of the descriptor and the original <query expression> of the
            descriptor.
        c) 情形 :  
       ......
   d) 如果V是有效可更新,  并且相应的QE中的列是可更新的, 那么在每个列描述符中, 
        暗示着列可更新.
        
......   





[编辑] 2.2 视图本身的可更新性支持

create view中的 check option语句

CREATE VIEW语句中的 WITH [ CASCADED | LOCAL ] CHECK OPTION 都针对的可更新视图,因此理解为:视图创建语法中支持 WITH [ CASCADED | LOCAL ] CHECK OPTION 的SQL语言,其实现的视图 是可更新视图;否则为只读视图。


[编辑] 3.各数据库产品对可更新视图的支持和不同实现

[编辑] 3.1 MySQL 5.1

  MySQL  5.1 对视图的更新,只有直接操作视图这一种方式. 当且仅当, 视图

不包含3.1.2中所罗列的情形,则视图可被更新,且更新操作会执行到相应的基表 上。

[编辑] 3.1.1 创建视图语法
CREATE [OR REPLACE] [ALGORITHM = {UNDEFINED | MERGE | TEMPTABLE}]    
   VIEW view_name [(column_list)]    
   AS select_statement   
   [WITH [CASCADED | LOCAL] CHECK OPTION]
[编辑] 3.1.2 可更新视图说明

某些视图是可更新的。也就是说,可以在诸如UPDATE、DELETE或INSERT等语句 中使用它们,以更新基表的内容。对于可更新的视图,在视图中的行和基表中 的行之间必须具有一对一的关系。还有一些特定的其他结构,这类结构会使得 视图不可更新。更具体地讲,如果视图包含下述结构中的任何一种,那么它就 是不可更新的:


·         聚合函数(SUM(), MIN(), MAX(), COUNT()等)。

·         DISTINCT 

·         GROUP BY 

·         HAVING 

·         UNION或UNION ALL 

·         位于选择列表中的子查询

·         Join 

·         FROM子句中的不可更新视图

·         WHERE子句中的子查询,引用FROM子句中的表。

·         仅引用文字值(在该情况下,没有要更新的基本表)。

·         ALGORITHM = TEMPTABLE(使用临时表总会使视图成为不可更新的)。
           关于可插入性(可用INSERT语句更新),如果它也满足关于视图列的
           下述额外要求,可更新的视图也是可插入的:

·         不得有重复的视图列名称。

·         视图必须包含没有默认值的基表中的所有列。

·         视图列必须是简单的列引用而不是导出列。导出列不是简单的列引用,
          而是从表达式导出的。下面给出了一些导出列示例:

              ·      3.14159            
            ·      col1 + 3                
            ·      UPPER(col2)               
            ·      col3 / col4               
            ·      (subquery)混合了简单列引用和导出列的视图是不可插入的,
                         但是,如果仅更新非导出列,视图是可更新的。

考虑下述视图:

CREATE VIEW v AS SELECT col1, 1 AS col2 FROM t; 该视图是不可插入的,这是因为col2是从表达式导出的。 但是,如果更新时不更新col2,它是可更新的。这类更新是允许的:

UPDATE v SET col1 = 0;

下述更新是不允许的,原因在于,它试图更新导出列:

UPDATE v SET col2 = 0;

在某些情况下,能够更新多表视图,假定它能使用MERGE算法进行处理。 为此,视图必须使用内部联合(而不是外部联合或UNION)。此外, 仅能更新视图定义中的单个表,因此,SET子句必须仅命名视图中某 一表的列。即使从理论上讲也是可更新的,不允许使用UNION ALL的视图, 这是因为,在实施中将使用临时表来处理它们。

对于多表可更新视图,如果是将其插入单个表中,INSERT能够工作。不支持DELETE。

对于可更新视图,可给定WITH CHECK OPTION子句来防止插入或更新行, 除非作用在行上的select_statement中的WHERE子句为“真”。

在关于可更新视图的WITH CHECK OPTION子句中,当视图是根据另一个视图 定义的时,LOCAL和CASCADED关键字决定了检查测试的范围。LOCAL关键字对 CHECK OPTION进行了限制,使其仅作用在定义的视图上,CASCADED会对将进 行评估的基表进行检查。如果未给定任一关键字,默认值为CASCADED。 请考虑下述表和视图集合的定义:

mysql> CREATE TABLE t1 (a INT);
mysql> CREATE VIEW v1 AS SELECT * FROM t1 WHERE a < 2 WITH CHECK OPTION;
mysql> CREATE VIEW v2 AS SELECT * FROM v1 WHERE a > 0 WITH LOCAL CHECK OPTION;
mysql> CREATE VIEW v3 AS SELECT * FROM v1 WHERE a > 0 WITH CASCADED CHECK OPTION;

这里,视图v2和v3是根据另一视图v1定义的。v2具有LOCAL检查选项,因此, 仅会针对v2检查对插入项进行测试。v3具有CASCADED检查选项,因此, 不仅会针对它自己的检查对插入项进行测试,也会针对基本视图的检查对插 入项进行测试。在下面的语句中,介绍了这些差异:

mysql> INSERT INTO v2 VALUES (2);
Query OK, 1 row affected (0.00 sec)
mysql> INSERT INTO v3 VALUES (2);
ERROR 1369 (HY000): CHECK OPTION failed 'test.v3'

视图的可更新性可能会受到系统变量updatable_views_with_limit的值的影响。请参见 “服务器系统变量”(http://dev.mysql.com/doc/refman/5.1/zh/database-administration.html#server-system-variables)。


[编辑] 3.1.3 MySQL对视图的限制
      关于视图的可更新性,对于视图,其总体目标是,如果任何视图从理论

上讲是可更新的,在实际上也应是可更新的。这包括在其定义中有UNION的视图。 目前,并非所有理论上可更新的视图均能被更新。最初的视图实施有意采用该方 式,为的是尽快地在MySQL中获得有用的可更新视图。很多理论上可更新的视图 现已能更新,但限制依然存在:

  • 其子查询位于WHERE子句之外任何位置的可更新视图。对于某些其子查询位于SELECT列表中的视图,也是可更新的。
  • 不能使用UPDATE来更新定义为Join的视图的1个以上的基表。
  • 不能使用DELETE来更新定义为Join的视图

引用参见:http://dev.mysql.com/doc/refman/5.1/zh/restrictions.html#view-restrictions


[编辑] 3.2 PostgreSQL 8.1

PostgreSQL8.1中定义的视图目前都是只读的。对视图的更新操作,只能通过 用户创建的重写规则来实现。

来源参见:http://www.pgsqldb.org/pgsqldoc-8.1c/sql-createview.html

[编辑] 3.2.1 创建视图语法
CREATE [ OR REPLACE ] [ TEMP | TEMPORARY ] VIEW name [ ( column_name [, ...] ) ]
    AS query
[编辑] 3.2.2 PostgreSQL视图简介

CREATE VIEW 定义一个查询的视图。 这个视图不是物理上实际存在(于磁盘)的。 具体的说,自动生成一个改写索引规则(一个 ON SELECT 规则)的查询用以支持在视图上的检索。

CREATE OR REPLACE VIEW 类似,不过是如果一个同名的视图已经存在,那么就替换它。 你只能用一个生成相同字段的新查询替换一个视图(也就是说,同样字段名和数据类型)。

目前,视图是只读的:系统将不允许在视图上插入,更新,或者删除数据。

[编辑] 3.2.3 对视图更新的可行方法

PostgreSQL支持规则系统,其中允许用户自定义重写规则,即定义一个规则, 它可以在指定事件发生时,用定义的操作代替原事件的操作。这样就可以把 一个对视图的操作,用无条件的INSTEAD规则来实现。你可以通过在视图上创 建把插入等动作重写为向其它表做合适操作的规则来实现可更新视图的效果。

参见 http://www.pgsqldb.org/pgsqldoc-8.1c/sql-createrule.html



[编辑] 3.3 DB2 v8

[编辑] 3.3.1 创建视图语法

%ATTACHURL%/create_view_DB2.jpg

[编辑] 3.3.2 DB2视图简介

DB2将视图区分为可删除视图、可更新视图、可插入视图、只读视图、不可用视图。

下面摘译一些手册中的说明。译错或者译不出的部分敬请指出或改正。

以下说明源自IBM UDB的英文版手册*_SQL Reference Volume 2 (version 8)_*,我简要翻译了一下。

  • 可删除视图*: 如果一个视图上被定义了关于delete操作的 INSTEAD OF 触发器,那么这个视图是可删除视图。或者,如果下列条件都成立,那么视图也是可删除视图:
  * 外层fullselect(outer fullselect)声明中的FROM 子句只能包含一个基表(with no OUTER clause),可删除视图 (with no OUTER clause), 可删除的嵌套的表表达式(原文:deletable nested table expression),或者可删除的公共表表达式(原文:deletable common table expression)(cannot identify a nickname)
  * 外层 fullselect 不包含 VALUES 子句
  * 外层 fullselect 不包含 GROUP BY 或 HAVING 子句
  * 外层 fullselect 的选择列表中不包含对列的函数
  * 外层 fullselect 不包含集合操作(UNION, EXCEPT 或 INTERSECT),但 UNION ALL 除外
  * 出现在UNION ALL 中的基表必须是不同的表,并且每一个基表都必须是可删除的
  * 外层 fullselect 的选择列表中不包含 DISTINCT
  • 可更新视图*: 如果视图的一个字段上被定义了关于update操作的 INSTEAD OF 触发器,那么这个字段是可更新的。或者,如果下面条件都成立,那么视图上的字段也是可更新的:
  * 视图是可删除视图 (不论是否是由关于delete的INSTEAD OF 触发器定义的),该列对应到一个基表的列(not using a dereference operation), 并且没有指明 READ ONLY 选项
  * 如果视图的fullselect包含UNION ALL,那么UNION ALL 中所有操作表涉及到的所有有关列,有精确的匹配

如果视图中的任何列都是可更新的,那么这个视图就是可更新视图(原文:A view is updatable if *any* column of the view is updatable)。

  • 可插入视图*:
  * 如果一个视图上被定义了关于insert操作的 INSTEAD OF 触发器,那么这个视图是可插入视图。或者这个视图中至少一列是可更新的(不论是否是由关于delete的INSTEAD OF 触发器定义的), 并且视图的fullselect 中不包含UNION ALL.
  * 当且仅当一个给定的行完成了视图对应的基表上的约束检查,该行才可能被插入到视图(包括UNION ALL视图)
  * 如果要插入的视图含有不可更新列,那么insert 对列的列表中,必须不包括这些列
  • 只读视图*: 如果视图不是可删除视图、可更新视图、或可插入视图,那么这个视图是只读视图。如果一个视图是不考虑INSTEAD OF 情况下的只读视图,那么SYSCAT.VIEWS 中的READONLY 列将被标记。
  • 不可用视图*: 不可用视图指对于SQL语句,该视图不再可用。当出现下列情况,视图将不可用:
  * 视图定义所依赖的特权被revoke
  * 视图定义所依赖的对象,如表、昵称、别名或者函数,被drop
  * 视图定义所依赖的另一个视图,变成不可用视图
  * A view that is the superview of the view definition (the subview) becomes inoperative.
[编辑] 3.3.3 对视图更新的可行方法

(1)根据3.3.2中给出的视图种类的说明,可知满足“可更新视图”的视图,都可直接通过SQL语句进行更新操作。分析上述的说明,可见DB2的可更新视图:

  * 允许更新某些UNION ALL视图 
  * 不允许更新象ORACLE支持的连接查询视图 

(2) DB2也可以用INSTEAD OF 触发器来实现视图的更新操作。 详细的信息还请参考http://www-128.ibm.com/developerworks/cn/db2/library/techarticles/0210rielau/0210rielau.html

[编辑] 3.4 Oracle

ORACLE允许用“WITH READ ONLY”子句显式地指定视图是只读的。若视图不带上述子句,则ORACLE遵照SQL标准提出了以下限制:

  * 不能有集合操作(UNION,UNION ALL,INTERSECT,MINUS) 
  * 不能有DISTINCT 
  * 不能有聚集函数(AVG,COUNT,MAX,MIN等)和分析函数 
  * 不能有GROUP BY,ORDER BY,CONNECT BY,START WITH 
  * SELECT列表中不能出现collection expression 
  * SELECT列表中不能有子查询 
  * 一般不能是JOIN查询(参见Oracle参考文献) 
  * SELECT列表中若出现系统的伪列或表达式,则更新语句不能修改这些列 
  * 可更新的连接视图要满足一些额外的条件

简单的说,视图定义中用到的基本表必须是“键值保持表”。(A base table of a view is considered a key-preserved table if every primary-key or unique-key value in the base table is also unique in the result set of the join view—in other words, if the entity integrity of the base table is preserved by the join view. )

  我们还可以用INSTEAD OF 触发器来实现视图的更新。

详细的信息还请参考文献Oracle, http://otn.oracle.com, Oracle 9i SQL Reference。


[编辑] 3.5 SQL Server2000

可以按下列方式通过视图修改数据:

a 使用具有支持 INSERT、UPDATE 和 DELETE 语句的逻辑的 INSTEAD OF 触发器。

b 使用修改一个或多个成员表的可更新分区视图。

c 如果视图不使用 INSTEAD OF 触发器或者不是可更新分区视图,则只要符合3.5.2中的条件,仍可更新:

[编辑] 3.5.1 INSTEAD OF 触发器
 INSTEAD OF 触发器不能在 WITH CHECK OPTION 的可更新视图上定义.
 引用自http://blog.csdn.net/taojiayu/archive/2006/10/24/1348966.aspx
 仅供参考。
[编辑] 3.5.2 分区视图
  使用 UNION ALL 运算符的分区视图是可更新视图。
  分布式分区视图(远程视图)不能使用键集驱动游标更新。此项限制可通过在基础
  表上而不在视图本身上声明游标得到解决。 


[编辑] 3.5.3 对情形c的一些限制条件

(1)如果视图不使用 INSTEAD OF 触发器或者不是可更新分区视图,则只要符合下面的条件,仍可更新:

引用自 联机帮助:

  • 视图在视图定义的 FROM 子句中包含至少一个表;视图不能只基于一个表达式。


  • 在选择列表中没有使用聚合函数(AVG、COUNT、SUM、MIN、MAX、GROUPING、
 STDEV、STDEVP、VAR、VARP)或 GROUP BY、UNION、DISTINCT 或 TOP 子句。
 但是,可以在 FROM 子句定义的子查询范围内使用聚合函数,前提条件是聚
 合函数生成的派生值没有修改过。 
  • 在选择列表中不使用派生列。派生列是由除简单列引用以外的一切构成的结果集列。


(2)此外,如果在视图中删除数据:

在视图定义的 FROM 子句中只能列出一个表。


(3)不能在视图中与text、ntext 或 image 列一起使用 READTEXT 和 WRITETEXT 语句。

[编辑] 3.5.4 对情形c的数据修改准则

不使用 INSTEAD OF 触发器或可更新分区视图而通过视图修改数据之前, 请考虑下列准则:

  • 如果在视图定义中使用了 WITH CHECK OPTION 子句,则所有在视图上
  执行的数据修改语句都必须符合定义视图的 SELECT 语句中所设定的条件。
  如果使用了 WITH CHECK OPTION 子句,修改行时需注意不让它们在修改
  完成后从视图中消失。任何可能导致行消失的修改都会被取消,
  并显示错误信息。


  • SQL Server 必须能够明确地解析对视图所引用基表中的特定行所做的
  修改操作。不能在一个语句中对多个基础表使用数据修改语句。
  因此,列在 UPDATE 或 INSERT 语句中的列必须属于视图定义中的
  同一个基表。


  • 对于基础表中需更新而又不允许空值的所有列,它们的值在 INSERT
  语句或 DEFAULT 定义中指定。这将确保基础表中所有需要值的列都
  可以获取值。


  • 在基础表的列中修改的数据必须符合对这些列的约束,如可否为空、
  约束、DEFAULT 定义等。例如,如果要删除一行,则相关表中的所有基
  础 FOREIGN KEY 约束必须仍然得到满足,删除操作才能成功。



[编辑] 3.5.5 其他参考

以下摘自《SQL Server 2000宝典》 中国铁道出版社 2004年3月第一版: page 269-270:

       “事实上,除了用简单的select语句创建的视图以外,其他的视图都不能

用来更新数据。”

  • 只能对一个表进行更新. 如果视图包含了连接操作,那么引用视图的
  update语句必须只对其中的一个表进行修改。
  • 可以使用视图或者基表上的instead of 触发器来对数据修改操作进行变更。
  • 如果在视图中包含了group by 子句,那么视图就是不可更新的。
  • 如果在视图中把一个子查询作为导出表来引用,那么就不能将这个导出表
   中的任何一列作为视图的列输出 (flying:此句没有懂)
  • 如果视图包含了with check option,那么对视图的insert和update操作就
   必须满足where子句中的条件要求
  • 要对之进行insert或者update 操作的列必须对应于基础表中的唯一一个列。
   如果同一个列名出现在两个表中,就应该在选择列表中明确地使用
   table.column的方式来唯一的标识它。




[编辑] 3.6 Sybase

[编辑] 4 小结

  主要的几个 DBMS 都实现了 SQL92 定义的可更新视图,SQL99 定义的可更新视图也或多或少的得到了支持。但是需要注意的是,产品之间对可更新视图的实现程度是有差异的,而且由于它们支持的SQL语法存在一些差异,要书写可移植的 SQL 语句需要特别注意。



--- 作者: 方丽英 liying_fang(at)yahoo(dot)com(dot)cn -- Main.FlyingFang - 11 Oct 2006

注:如要转载请注明作者和出处 www.pgsqldb.org 或 liying_fang(at)yahoo(dot)com(dot)cn

Personal tools