2011-05-26 85 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