相关的文档10bet官方网站 下载本手册
PDF(美国Ltr)- 41.9 mb
PDF (A4)- 42.0 mb
手册(TGZ)- 266.1 kb
手册(Zip)- 376.0 kb
信息(Gzip)- 4.0 mb
信息(邮政编码)- 4.0 mb
本手册节选

25.5.3可更新和插入表视图

有些视图是可更新的,对它们的引用可用于在数据更改语句中指定要更新的表。也就是说,你可以在这样的语句中使用它们更新删除,或插入来更新基础表的内容。派生表和公共表表达式也可以在多表中指定更新而且删除语句,但只能用于读取数据以指定要更新或删除的行。通常,视图引用必须是可更新的,这意味着它们可以被合并而不被物化。复合视图有更复杂的规则。

要使视图可更新,视图中的行与底层表中的行之间必须存在一对一的关系。还有一些其他的构造使视图不可更新。更具体地说,如果视图包含以下任何一个,则不可更新:

  • 聚合函数或窗口函数(SUM ()MIN ()MAX ()COUNT (),等等)

  • 截然不同的

  • 集团

  • 联盟UNION ALL

  • 选择列表中的子查询

    选择列表中的非相关子查询失败插入,但是可以更新删除.对于选择列表中的相关子查询,不允许使用任何数据更改语句。

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

  • 类中不可更新视图的引用条款

  • 的子查询在哪里中引用表的子句条款

  • 只引用文字值(在本例中,没有要更新的底层表)

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

  • 对基表任意列的多次引用(对于插入好的更新删除

视图中生成的列被认为是可更新的,因为可以给它赋值。但是,如果显式更新了这样的列,则惟一允许的值为默认的.有关已生成列的信息,请参见第13.1.20.8节“创建表和生成的列”

方法可以对多表视图进行处理,那么它有时可能是可更新的合并算法。为此,视图必须使用内部连接(而不是外部连接或联盟).此外,只能更新视图定义中的单个表,因此子句必须只命名视图中一个表的列。视图使用UNION ALL是不允许的,尽管理论上它们可能是可更新的。

关于可插入性(可以用插入语句),一个可更新的视图是可插入的,如果它也满足这些额外的视图列的要求:

  • 视图列名不能重复。

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

  • 视图列必须是简单的列引用。它们不能是这样的表达:

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

MySQL设置了一个标志,称为视图更新标志创建视图时间。旗帜设置为是的(真正的)如果更新而且删除(以及类似的操作)对于视图是合法的。否则,将标志设置为没有(假)。的IS_UPDATABLE列中的INFORMATION_SCHEMA。的观点表显示此标志的状态。这意味着服务器总是知道视图是否可更新。

如果一个视图是不可更新的,语句更新删除,插入是非法的,并且被拒绝。(即使视图是可更新的,也可能无法插入到其中,如本节其他部分所述。)

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

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

CREATE TABLE t1 (x INTEGER);CREATE TABLE t2 (c INTEGER);CREATE VIEW vmat AS SELECT (x) AS s FROM t1;CREATE VIEW vup AS SELECT * FROM t2;CREATE VIEW vjoin AS SELECT * FROM vmat JOIN vup ON vmat.s=vup.c;

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

  • 插入:对象的插入表插入语句可以是被合并的视图引用。如果视图是连接视图,则视图的所有组件都必须是可更新的(不是物化的)。对于多表可更新视图,插入如果它插入到单个表中,则可以工作。

    该语句无效,因为连接视图的一个组件是不可更新的:

    INSERT INTO vjoin (c) VALUES (1);

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

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

    在多重表中更新语句时,语句的更新表引用必须是基表或可更新视图引用。非更新的表引用可以是物化视图或派生表。

    这种说法是有效的;列c来自连接视图的可更新部分:

    UPDATE vjoin SET c=c+1;

    这个陈述是无效的;列x来自不可更新部分:

    UPDATE vjoin SET x=x+1

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

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

    这个陈述是无效的;它尝试更新一个物化的派生表:

    更新vup JOIN (SELECT SUM(x) AS s FROM t1) AS dt ON…集合s = s + 1;
  • 删除中要删除的一个或多个表删除语句必须是合并视图。不允许连接视图(这与插入而且更新).

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

    删除vjoin WHERE…;

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

    删除vup WHERE…;

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

    DELETE vup FROM vup JOIN (SELECT SUM(x) AS s FROM t1) AS dt ON…;

下面是更多的讨论和示例。

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

CREATE VIEW v AS SELECT col1, 1 AS col2 FROM t;

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

SET col1 = 0;

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

SET col2 = 0;

如果表中包含AUTO_INCREMENT属性的表上的可插入视图AUTO_INCREMENT的值不变LAST_INSERT_ID (),因为将默认值插入到不是视图一部分的列的副作用不应该是可见的。