定義視圖后,對視圖的查詢沒有什么限制,可以像對待表一樣進行操作。但是,如果對視圖中的元組進行更新操作(INSERT,UPDATE,DELETE)將受到限制。概括起來,關於可更新視圖有以下三條規則:
(1) 若視圖是基於多個表使用聯接操作而導出的,那么對這個視圖執行更新操作時,每次只能影響其中的一個表。
(2) 若視圖導出時包含有分組和聚合操作,則不允許對這個視圖執行更新操作。
(3) 若視圖是從一個表經選擇、投影而導出的,並在視圖中包含了表的主鍵字或某個候選鍵,這類視圖稱為‘行列子集視圖’。對這類視圖可執行更新操作。
定義可更新視圖時加上WITH CHECK OPTION短語,表示強制在視圖上的所有數據更新語句都必須符合由select查詢語句所設置的准則。
由於視圖不一定包括表中的所有字段,所以在插入記錄時可能會遇到問題。視圖中那些沒有出現的字段無法顯式插入數據,假如這些字段不接受系統指派的null值,那么插入操作將失敗。但這類視圖仍然可以用於修改和刪除操作。
·設有下面的視圖定義:
use mydb go CREATE VIEW s_e_c_view as SELECT student.sno,sname,cname,grade FROM student,elective,course WHERE student.sno=elective.sno and elective.cno=course.cno
這個視圖由三個表聯接而成。如果對該視圖執行下列插入操作:
use mydb INSERT INTO s_e_c_view VALUES ( 200200130, ’張小冬’, ’english’, 82 )
系統將發出錯誤信息:“視圖或函數‘s_e_c_view’不可更新,因為修改會影響多個基表”。我們不妨假設在表course中,一個非鍵字段值(課程名cname)可能對應多個主鍵值(課程號cno)。現在只有課程名‘english’而主鍵課程號cno不確定,顯然不能把數據插入course表中。同樣,由於cno不確定,也不能把成績82插到elective表中。因此,不允許對這個視圖執行插入操作。這里的s_e_c_view視圖屬於規則(1)所述的情形。
如果把插入操作換成修改操作,而且只影響其中一個表,同時新數據值中含有主鍵字,系統將接受這個修改操作。實例如下:
use mydb
UPDATE s_e_c_view SET sno=200200130, sname='張小冬' WHERE sno=200200102
·設有下面的視圖定義:
use mydb go CREATE VIEW e_view ( sno, c_amounnt, avg_grade ) as SELECT sno,count(cno),avg(grade) FROM elective WHERE grade is not null GROUP BY sno
這個視圖雖然僅從一個表中導出,但導出時使用了分組和聚合操作。如果對該視圖執行下列插入操作:
use mydb
INSERT INTO e_view VALUES ( 200200120, 2, 78 )
系統將發出錯誤信息:“視圖或函數‘e_view' 不可更新,因為它包含聚合”。
事實上,在原來的elective表中根本就不存在‘修課總數’和‘平均成績’兩列。上述的更新操作顯然不切實際。因此,不允許對這個視圖執行更新操作是合理的。這里的e_view視圖屬於規則(2)所述的情形。
·設有下面的視圖定義:
use mydb go
CREATE VIEW s_view as SELECT sno,sname,height FROM student WHERE sex=’男’
這個視圖基於一個表且只使用選擇和投影操作,同時還包含了主鍵字sno,所以這個視圖是可更新的。如果對該視圖執行下列插入操作:
use mydb
INSERT INTO s_view VALUES ( 200200120, '黃大春', 178 )
在student表中將插入一個新的記錄,對記錄中沒有指定值的字段系統將指派一個NULL值。這里的s_view視圖屬於規則(3)所述的情形。
關於可更新視圖的一些更具體的描述如下。
如果視圖沒有INSTEAD OF觸發器,或者視圖不是分區視圖,則視圖只有滿足下列條件才可更新:
select語句在選擇列表中沒有聚合函數,也不包含TOP,GROUP BY,UNION(除非視圖是分區視圖)或DISTINCT子句。聚合函數可以用在FROM子句的子查詢中,只要不修改函數返回的值。
select語句的選擇列表中沒有派生列。派生列是由任何非簡單列表達式(使用函數、加法或減法運算符等)所構成的結果集列。
select語句中的FROM子句至少引用一個表。select語句不能只包含非表格格式的表達式(即不是從表派生出的表達式)。
INSERT,UPDATE和DELETE語句在引用可更新視圖之前,也必須如上述條件指定的那樣滿足某些限制條件。只有當視圖可更新,並且所編寫的UPDATE或INSERT語句只修改視圖的FROM子句引用的一個基表中的數據時,UPDATE和INSERT語句才能引用視圖。只有當視圖在其FROM子句中只引用一個表時,DELETE語句才能引用可更新的視圖。