SQL server中視圖的更新

SQL Server中更新視圖, 可能出現的錯誤及處理. 
        定義視圖後,對視圖的查詢沒有什麼限制,可以像對待表一樣進行操作。但是,
如果對視圖中的元組進行更新操作(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不確定,也不能把成績8


2插到elective表中。因此,不允許對這個視圖執行插入操作。這裏的s_e_c_vie


w視圖屬於規則(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語句才能引用可更


新的視圖。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章