1. 程式人生 > >細說Sql Server中的檢視(上)(更新)

細說Sql Server中的檢視(上)(更新)

1,什麼是檢視?

            2,為什麼要用檢視;

            3,檢視中的ORDER BY;

            4,重新整理檢視;

            5,更新檢視;

            6,檢視選項;

            7,索引檢視;


        細說Sql Server中的檢視(下)    應大家要求已在“細說Sql Server中的檢視(上)”中新增“為什麼要用檢視”一小節。

1.什麼是檢視

   檢視是由一個查詢所定義的虛擬表,它與物理表不同的是,檢視中的資料沒有物理表現形式,除非你為其建立一個索引;如果查詢一個沒有索引的檢視,Sql Server實際訪問的是基礎表。

   如果你要建立一個檢視,為其指定一個名稱和查詢即可。Sql Server只儲存檢視的元資料,使用者描述這個物件,以及它所包含的列,安全,依賴等。當你查詢檢視時,無論是獲取資料還是更新資料,Sql server都用檢視的定義來訪問基礎表;

   檢視在我們日常操作也扮演著許多重要的角色,比如可以利用檢視訪問經過篩選和處理的資料,而不是直接訪問基礎表,以及在一定程度上也保護了基礎表。

   我們在建立檢視的時候,也要遵守三個規則:

    1. 不能在檢視定義中指定ORDER BY ,除非定義中包含Top或For Xml 說明;
    2. 所有的列必須有列名;
    3. 這些所有的列名必須唯一;

    對於視圖表中在沒有top或for xml說明的情況下,不能有Order by 語句,這是因為檢視被認為是一個表,表是一個邏輯的實體,它的行是沒有順序的。檢視中所有列必須有列名,且唯一的情況我想大家都理解;

下面的sql語句表示建立一個簡單的檢視:

   1:  CREATE VIEW dbo.V1
   2:  AS
   3:  SELECT CustomerID,CompanyName FROM Customers 
   4:  WHERE EXISTS(SELECT * FROM Orders WHERE Customers.CustomerID = Orders.CustomerID)
2.為什麼要使用檢視(更新)
   SqlServer既然給我們提供這樣的物件,就一定有它的作用。而我們在使用檢視上,要麼用的過多,要麼用的不夠,所以一部分人建議不要用檢視,而一部分人又建議少用。那我們聽誰的呢?
      其實我們要是掌握了用檢視的目的,就能在正確的地方,用正確的檢視;那麼檢視能給我們解決什麼問題呢?
            1,為終端使用者減少資料庫呈現的複雜性。客戶端只要對檢視寫簡單的程式碼,就能返回我所需要的資料,一些複雜的邏輯操作,放在了檢視中來完成;
            2,防止敏感的列被選中,同時仍然提供對其他重要資料的訪問;
            3,對檢視新增一些額外的索引,來提高查詢的效率;
      檢視其實沒有改變任何事情,只是對訪問的資料進行了某種形式的篩選。考慮一下檢視的作用,你應該能看到檢視的概念如何為缺乏經驗的使用者簡化資料(只顯示他們關心的資料),或者不給予使用者訪問基礎表的
權利,但授予他們訪問不包含敏感資料檢視的權力,從而提前隱藏敏感資料。
      要知道,在預設的情況下,檢視沒有做什麼特殊的事情。檢視就好象一個查詢那樣從命令列執行(這裡不存在任何形式的預先優化),這意味著在資料請求和將被交付的資料之間多加了一層開銷。這表明檢視絕不可能像
只是直接執行底層SELECT語句那樣快。不過,檢視存在有一個原因--這就是它的安全性或為使用者所做的簡化,在你的需要和開銷之間權衡,找到最適合特定情況的解決方案。
3.檢視中的ORDER BY
    視圖表示一個邏輯實體,它與表非常類似;
    如果我們在上面的建立的sql語句中加一個Order BY 語句,看看有什麼效果:
   1:  ALTER VIEW dbo.V1
   2:  AS 
   3:  SELECT CustomerID,CompanyName FROM Customers 
   4:  WHERE EXISTS(SELECT * FROM Orders WHERE Customers.CustomerID = Orders.CustomerID)  
   5:  ORDER BY CompanyName

執行該語句將會失敗,回收到以下的提示:

Msg 1033, Level 15, State 1, Procedure V1, Line 5 
除非另外還指定了 TOP 或 FOR XML,否則,ORDER BY 子句在檢視、行內函數、派生表、子查詢和公用表表達式中無效。

根據提示,ORDER By 也不是不能用,只有指定了Top或for xml語句後,ORDER BY 才能使用,如: 
 

   1:  ALTER VIEW dbo.V1
   2:  AS 
   3:  SELECT TOP(10) CustomerID,CompanyName FROM Customers 
   4:  WHERE EXISTS(SELECT * FROM Orders WHERE Customers.CustomerID = Orders.CustomerID)  
   5:  ORDER BY CompanyName

      但是,並不建議在檢視中使用ORDER BY ,這是因為視圖表示一個表,而對於表來說,是不會有排序的;所以建議在查詢檢視的時候,用ORDER BY;

      SQL Server2005聯機叢書有一段這樣的描述:“在檢視、行內函數、派生表或子查詢的定義中使用ORDER BY 字句,子句只能使用者確定TOP子句返回的行。ORDER BY 不保證在查詢這些構造時得到有序結果,除非在查詢本省也指定了ORDER BY.”

4.重新整理檢視

我在上面說過,檢視會儲存元資料,列,安全,以及依賴等資訊,如果我們把基礎表的架構更改了,並不會直接反映到檢視上來;更改架構後,使用sp_refreshview儲存過程重新整理檢視的元資料是一個好習慣;

比如我們建立了一個表T1和一個T1的檢視V1,然後更改T1,再看V1的結果:

首先建立表T1: 

   1:  IF OBJECT_ID('T1') IS NOT NULL
   2:      DROP TABLE T1
   3:   
   4:  CREATE TABLE T1(col1 INT,col2 INT)
   5:  INSERT INTO T1(col1,col2) VALUES(1,2)
   6:  GO

然後建立T1的檢視V1:

   3:  CREATE VIEW V1
   4:  AS 
   5:  SELECT * FROM T1

       在現實實踐中,要避免在檢視中的SELECT語句中使用*,在這只是演示。如果你查詢檢視V1就會出現以下結果: 
        tmp16

       接下來,我們對錶T1新增一列col3: 
      

   1:  ALTER TABLE T1 ADD col3 INT

       然後再次查詢檢視V1,你想這時的結果是三列呢,還是而列呢?答案是二列。T1架構的改變,並沒有影響到檢視的元資料中,這時候,如果我們要重新整理一下檢視V1,我們就可以用:EXEC sp_refreshview V1 命令, 再次查詢,V1的結果就是三列了。

 不寫了,困了,明天再補全,就分上下二節吧

興百放

參考文獻:《T-SQL程式設計》

原文地址: