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語句才能引用可更

新的視圖。

 

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