1,什麼是視圖?
2,爲什麼要用視圖;
3,視圖中的ORDER BY;
4,刷新視圖;
5,更新視圖;
6,視圖選項;
7,索引視圖;
1.什麼是視圖
視圖是由一個查詢所定義的虛擬表,它與物理表不同的是,視圖中的數據沒有物理表現形式,除非你爲其創建一個索引;如果查詢一個沒有索引的視圖,Sql Server實際訪問的是基礎表。
如果你要創建一個視圖,爲其指定一個名稱和查詢即可。Sql Server只保存視圖的元數據,用戶描述這個對象,以及它所包含的列,安全,依賴等。當你查詢視圖時,無論是獲取數據還是更新數據,Sql server都用視圖的定義來訪問基礎表;
視圖在我們日常操作也扮演着許多重要的角色,比如可以利用視圖訪問經過篩選和處理的數據,而不是直接訪問基礎表,以及在一定程度上也保護了基礎表。
我們在創建視圖的時候,也要遵守三個規則:
不能在視圖定義中指定ORDER BY ,除非定義中包含Top或For Xml 說明;
所有的列必須有列名;
這些所有的列名必須唯一;
對於視圖表中在沒有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 NULL2: 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 V14: AS5: SELECT * FROM T1
在現實實踐中,要避免在視圖中的SELECT語句中使用*,在這只是演示。如果你查詢視圖V1就會出現以下結果:
接下來,我們對錶T1添加一列col3:
1: ALTER TABLE T1 ADD col3 INT
然後再次查詢視圖V1,你想這時的結果是三列呢,還是而列呢?答案是二列。T1架構的改變,並沒有影響到視圖的元數據中,這時候,如果我們要刷新一下視圖V1,我們就可以用:EXEC sp_refreshview V1 命令, 再次查詢,V1的結果就是三列了。