2011-05-26 56 views
1

我有几个与在MySQL检查选项有关的问题:创建视图 - WITH CHECK OPTION

1)我知道with check option不添加不满足于用来定义子选择查询WHERE条款记录一个视图,但是如果没有选择with check option会发生什么情况?为什么会添加不符合WHERE子句的行?

2)LOCAL/CASCADEDwith check option有什么区别?

+0

你正在使用哪个服务器? MSSQL,PostgreSQL,Oracle? – Johan 2011-05-26 11:35:28

+0

哎呀,我正在使用MYSQL – user559142 2011-05-26 11:53:34

回答

3

当您执行UPDATE时,可以多想一想。当您对基表执行UPDATE,然后执行SELECT时,刚刚更新的行仍然存在。

现在,假设基于它们的ID 2和5之间是从基表中选择的行,一个图,用户运行这些查询:

SELECT * from View 
UPDATE View set ID = ID + 3 
SELECT * from View 

现在,突然间,行已经消失。

4

没有WITH CHECK OPTION,更新(INSERT/UPDATE/MERGE/DELETE等)所观看的表将导致它的底层基表中被更新,而不管WHERE子句VIEW的(假设的DBMS认为视图是可更新) 。如果INSERT连接到不符合WHERE子句的VIEW,然后刷新VIEW,则新插入的行在VIEW中将不可见。 WITH CHECK OPTION可以防止这种“奇怪”的情况发生,但除此之外还有更多。

考虑创建一个VIEW,以允许某个用户(用户组,应用程序等)仅查看表中某一行的子集,例如以允许他们查看员工的数据,同时阻止他们查看管理人员的详细信息:撤消该用户对基表的读取权限,而是在视图上授予他们。 WITH CHECK OPTION允许您为写权限执行相同的操作,在这种情况下,如果它会创建执行雇员行,则会阻止INSERT查看视图。

可以使用类似的技术来实施“行级别”约束,例如,公司只能通过强制INSERT通过VIEWWHERE条款只允许每个公司有一名员工而拥有一位总裁。


你怎么定义 “一个公司只能有一个总统”

这里有一个简单的例子条件(无FKS等),使用标准的SQL:

CREATE TABLE Employees 
(company_id CHAR(8) NOT NULL, 
    employee CHAR(10) NOT NULL UNIQUE, 
    job_title VARCHAR(20) NOT NULL); 

CREATE VIEW Presidents 
AS 
SELECT * 
    FROM Employees 
    WHERE job_title = 'president' 
    AND 1 >= (SELECT COUNT(*) 
       FROM Employees e 
       WHERE e.job_title = 'president' 
       GROUP 
        BY e.company_id) 
WITH CHECK OPTION; 

INSERT INTO Employees VALUES ('Acme', '1', 'president'); 
INSERT INTO Employees VALUES ('Acme', '2', 'president'); 

第二次插入失败,因为它会使公司Acme的总裁人数大于1,因此查询的“子查询”部分会导致新总裁从视图的结果集中移除,事务被有效地回滚。

+0

你能举一个你在最后一段中说的话吗?可更新视图有一些限制,即不具有“分组”,“具有”,“汇总功能”等。那么如何定义“公司只能有一位总裁”的条件呢? – 2017-09-09 09:12:24