23.5.4 带有检查选项子句的视图
可以为可更新视图提供WITH CHECK OPTION
子句,以防止插入* select_statement
*中WHERE
子句不为真的行。它还可以防止对WHERE
子句为 true 的行进行更新,但更新将导致该更新为不正确(换句话说,它可以防止将可见行更新为不可见行)。
在可更新视图的WITH CHECK OPTION
子句中,当使用另一个视图定义视图时,LOCAL
和CASCADED
关键字确定检查测试的范围。如果没有给出任何关键字,则默认值为CASCADED
。
在 MySQL 5.7.6 之前,WITH CHECK OPTION
测试的工作方式如下:
-
使用
LOCAL
,将检查视图WHERE
子句,但不检查基础视图。 -
使用
CASCADED
,将检查视图WHERE
子句,然后检查对基础视图的递归,将WITH CASCADED CHECK OPTION
添加到它们(出于检查目的;其定义保持不变),并应用相同的规则。 -
如果没有检查选项,则不检查视图
WHERE
子句,也不检查基础视图。
从 MySQL 5.7.6 开始,WITH CHECK OPTION
测试是符合标准的(与LOCAL
相比以前的语义有所更改,并且没有 check 子句):
-
使用
LOCAL
,将检查 viewWHERE
子句,然后检查递归到基础视图并应用相同的规则。 -
使用
CASCADED
,将检查视图WHERE
子句,然后检查对基础视图的递归,将WITH CASCADED CHECK OPTION
添加到它们(出于检查目的;其定义保持不变),并应用相同的规则。 -
如果没有检查选项,则不检查视图
WHERE
子句,然后递归检查基础视图并应用相同的规则。
考虑下 table 和视图集的定义:
CREATE TABLE t1 (a INT);
CREATE VIEW v1 AS SELECT * FROM t1 WHERE a < 2
WITH CHECK OPTION;
CREATE VIEW v2 AS SELECT * FROM v1 WHERE a > 0
WITH LOCAL CHECK OPTION;
CREATE VIEW v3 AS SELECT * FROM v1 WHERE a > 0
WITH CASCADED CHECK OPTION;
这里,v2
和v3
视图是根据另一个视图v1
定义的。在 MySQL 5.7.6 之前,由于v2
具有LOCAL
检查选项,因此仅针对v2
检查对插入进行测试。 v3
具有CASCADED
检查选项,因此不仅要针对v3
检查,还要针对基础视图的插入来测试插入。以下语句说明了这些差异:
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'
从 MySQL 5.7.6 开始,LOCAL
的语义与之前的有所不同:v2
的插入根据其LOCAL
check 选项进行检查,然后(与 5.7.6 之前的版本不同),该检查递归到v1
并再次应用规则。 v1
的规则导致检查失败。 v3
的检查与以前一样失败:
mysql> INSERT INTO v2 VALUES (2);
ERROR 1369 (HY000): CHECK OPTION failed 'test.v2'
mysql> INSERT INTO v3 VALUES (2);
ERROR 1369 (HY000): CHECK OPTION failed 'test.v3'