有些视图是可更新的,对它们的引用可用于在数据更改语句中指定要更新的表。也就是说,您可以在如下语句中使用它们更新
那删除
, 或者插入
更新基础表的内容。派生表也可以在多个表中指定更新
和删除
语句,但只能用于读取数据以指定要更新或删除的行。通常,视图引用必须是可更新的,这意味着它们可以合并而不实现。综合视图具有更复杂的规则。
对于可更新的视图,视图中的行与基础表中的行之间必须存在一对一的关系。还有一些其他结构使视图不可更新。更具体地说,如果一个视图包含以下任何一个,它就不是可更新的:
视图中的生成列被认为是可更新的,因为可以分配给它。但是,如果此类列是明确更新的,则唯一允许的值是默认
.有关生成的列的信息,请参见第13.1.18.7节“创建表和生成的列”.
控件处理多表视图时,有时多表视图可能是可更新的合并
算法。为此,视图必须使用内连接(而不是外连接或联盟
)。此外,只能更新视图定义中的单个表,所以放
条款必须只命名视图中的一个表中的列。使用的观点联盟全部
虽然它们可能是理论上更新,但也不允许。
关于可插入性(可用插入
语句),可更新视图可插入,如果它还满足视图列的这些其他要求:
必须没有重复的视图列名。
视图必须包含基表中没有默认值的所有列。
视图列必须是简单的列引用。他们不得表达,例如这些:
3.14159 col1 + 3 UPPER(col2) col3 / col4 (子查询)
MySQL设置了一个名为视图可更新性的标记at创建视图
时间。将标志设置为是的
(真正的)如果更新
和删除
(和类似的操作)是为了观看的合法性。否则,标志设置为没有
(假)。这IS_UPDATABLE
列INFORMATION_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()
,因为将默认值插入非视图部分列的副作用不应该是可见的。