相关的文档10bet官方网站 下载本手册 本手册摘录

MySQL 5.7参考手册/....../ 可更新和可插入的视图

23.5.3可更新和可插入的视图

有些视图是可更新的,对它们的引用可用于在数据更改语句中指定要更新的表。也就是说,您可以在如下语句中使用它们更新删除, 或者插入更新基础表的内容。派生表也可以在多个表中指定更新删除语句,但只能用于读取数据以指定要更新或删除的行。通常,视图引用必须是可更新的,这意味着它们可以合并而不实现。综合视图具有更复杂的规则。

对于可更新的视图,视图中的行与基础表中的行之间必须存在一对一的关系。还有一些其他结构使视图不可更新。更具体地说,如果一个视图包含以下任何一个,它就不是可更新的:

  • 聚合函数(和()MIN()最大限度()COUNT ()等等)

  • 清楚的

  • 集团

  • 拥有

  • 联盟联盟全部

  • 选择列表中的子查询

    在MySQL 5.7.11之前,选择列表中的子查询会失败插入,但对更新删除.截至MySQL 5.7.11,对于非竞争的子查询仍然是真的。对于“选择列表中的依赖子查询”,不允许使用数据更改语句。

  • 某些连接(请参阅本节稍后的其他连接讨论)

  • 参考不可PATABLE的视图条款

  • 子查询在在哪里语句中指向表的子句条款

  • 仅引用文字值(在本例中,没有要更新的基础表)

  • 算法=诱惑(使用临时表总是使视图不可更新)

  • 对基本表的任何列的多个引用(失败插入,好吧更新删除

视图中的生成列被认为是可更新的,因为可以分配给它。但是,如果此类列是明确更新的,则唯一允许的值是默认.有关生成的列的信息,请参见第13.1.18.7节“创建表和生成的列”

控件处理多表视图时,有时多表视图可能是可更新的合并算法。为此,视图必须使用内连接(而不是外连接或联盟)。此外,只能更新视图定义中的单个表,所以条款必须只命名视图中的一个表中的列。使用的观点联盟全部虽然它们可能是理论上更新,但也不允许。

关于可插入性(可用插入语句),可更新视图可插入,如果它还满足视图列的这些其他要求:

  • 必须没有重复的视图列名。

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

  • 视图列必须是简单的列引用。他们不得表达,例如这些:

    3.14159 col1 + 3 UPPER(col2) col3 / col4 (子查询

MySQL设置了一个名为视图可更新性的标记at创建视图时间。将标志设置为是的(真正的)如果更新删除(和类似的操作)是为了观看的合法性。否则,标志设置为没有(假)。这IS_UPDATABLEINFORMATION_SCHEMA。的观点表显示此标志的状态。

如果视图是不可更新的,则这样的语句更新删除,插入是非法的,并被拒绝。(即使视图是可更新的,也可能不可能将其插入,如本节其他部分所述。)

IS_UPDATABLE如果视图取决于一个或多个其他视图,则标志可能是不可靠的,并且更新这些底层视图中的一个。不管IS_UPDATABLE值时,服务器会跟踪视图的可更新性,并正确地拒绝对不可更新的视图的数据更改操作。如果IS_UPDATABLE视图的值已经变得不准确到由于底层视图的变化,可以通过删除和重新创建视图来更新值。

属性的值可能会影响视图的可更新性updatable_views_with_limit系统变量。看到第5.1.7节,“服务器系统变量”

对于以下讨论,假设存在这些表和视图:

创建表T1(x整数);创建表T2(C整数);创建视图vmat作为从t1的s sum(x);将视图Vup创建为Select * from T2;在vmat.s = vup.c上创建视图vjoin作为select * from vmat加入vup;

插入更新,删除允许的陈述如下:

  • 插入:插入表的插入语句可能是合并的视图引用。如果视图是连接视图,则视图的所有组件必须更新(未实现)。对于多表可更新视图,插入可以工作,如果它插入到单个表。

    此语句无效,因为加入视图的一个组件是不可扫描的:

    INSERT INTO vjoin (c) VALUES (1);

    这种说法是有效的;视图不包含重要组件:

    INSERT INTO vup (c) VALUES (1);
  • 更新:要更新的表格或表更新语句可以是被合并的视图引用。如果一个视图是一个连接视图,那么该视图中至少有一个组件必须是可更新的(这与插入)。

    在一个多桌子里更新语句,语句的更新表引用必须是基表或可更新的视图引用。非updated表引用可以是物化视图或派生表。

    这种说法是有效的;柱子C来自join视图的可更新部分:

    UPDATE vjoin SET c=c+1;

    此语句无效;柱子X来自不可更新部分:

    UPDATE vjoin SET x=x+1;

    这种说法是有效的;多表的更新表引用更新是一个可更新的视图(vup):

    UPDATE vup JOIN (SELECT SUM(x) AS s FROM t1) AS dt ON…集c = c + 1;

    此语句无效;它试图更新物化派生表:

    更新VUP JOIN(选择SUM(x)从t1),如dt在...设置s = s + 1;
  • 删除:要删除的一个或多个表删除声明必须合并视图。不允许加入视图(这与...不同插入更新)。

    这个语句无效,因为该视图是一个连接视图:

    删除vjoin哪里......

    此语句有效,因为视图是合并的(可更新)视图:

    删除VUP ...;

    这个语句是有效的,因为它从一个合并的(可更新的)视图中删除:

    从Vup Join中删除Vup(从T1选择Sum(x)),如dt ......;

额外的讨论和示例遵循。

本节前面的讨论指出,如果不是所有列都是简单的列引用(例如,如果包含表达式或复合表达式的列),则视图是不可插入的。虽然这样的视图不能插入,但如果只更新不是表达式的列,则可以更新它。考虑这一观点:

创建视图v作为选择col1,1为col2 from t;

此视图不可插入,因为COL2.是一个表达式。但如果更新不尝试更新,则它是可更新的COL2..这个更新是允许的:

UPDATE v SET col1 = 0;

此更新不允许,因为它尝试更新表达式列:

更新v设置col2 = 0;

如果表包含一个表AUTO_INCREMENT列,插入到不包括的表的可插入视图中AUTO_INCREMENT列的值不更改last_insert_id(),因为将默认值插入非视图部分列的副作用不应该是可见的。