(1)表準的SQL視圖
標準視圖比較簡單,大家也都在使用,在此就不壘述了。
(2)使用動態視圖
標準視圖有一個嚴重的侷限性,那就是標準視圖不支持參數。俗話說“法網恢恢,疏而不漏”,呵呵,我們也可以變通的使用帶參數的視圖。實現方法是我們把一個用戶定義的表值函數當作支持參數的動態視圖使用:
CREATE FUNCTION fnTestView (@m_id int)
RETURNS TABLE
AS
RETURN (select * from 視圖名稱 where 條件=@m_id)
這樣可以在Select語句的From子句中引用他們,用法:
Select * from fnTestView(2)
(3)使用索引視圖
我們在使用視圖的時候有時想怎麼能給視圖加索引呢,其實,視圖和普通的表一樣可以添加索引,當SQL Server必須聯合很多表時,這項技術可以大大提高Select語句的性能。
當在視圖上創建一個唯一聚集索引(unique clusterd index)時,SQL Server將物化這個視圖。看下面的例子:
CREATE VIEW dbo.vtUsers
WITH SCHEMABINDING
AS
SELECT dbo.tUsers.userid, dbo.tUsers.username, dbo.tUsers.password,
dbo.tUsers.question, dbo.tUsers.answer, dbo.tUsers.email, dbo.tUsers.realname,
dbo.tUsers.sex, dbo.tUsers.birthday, dbo.tUsers.country, dbo.tUsers.city,
dbo.tUsers.address, dbo.tUsers.zip, dbo.tUsers.tele, dbo.tUsers.exdate,
dbo.tUsers.totalfund, dbo.tUsers.ordertotal, dbo.tUsers.jifen, dbo.tUsers.pid,
dbo.tUsers.agentid, dbo.tUsers.agentid2, dbo.tUsers.agentid3, dbo.tUsers.status,
dbo.tUsers.checkmod, dbo.tUsers.account, dbo.tUsers.bank, dbo.tUsers.logip,
dbo.tUsers.sitename, dbo.tUserInfo.siteurl
FROM dbo.tUsers INNER JOIN
dbo.tUserInfo ON dbo.tUsers.userid = dbo.tUserInfo.userid
WHERE dbo.tUserInfo.UserID >20
CREATE UNIQUE CLUSTERED INDEX idxvtUser
ON vtUsers(userid)
儘管這個索引只引用了列的一個子集,但是這個索引包含葉級別節點中的所有列(每個聚集索引也都是這樣)。
和標準視圖一樣索引視圖的創建和使用也都是有限制的。一個標準視圖轉換爲一個索引視圖必須遵守以下規則:
A.視圖必須使用With Schemabinding選項來創建;
B.在這個視圖中不能使用其他視圖、導出表、行集函數或自查詢,也就是說只能使用表;
C.視圖所用到的基本表必須和視圖屬於同一個所有者;
D.視圖只能鏈接同一個數據庫中的表;
E.視圖不能包含一個外部鏈接或自鏈接,也就是說在鏈接表時只能使用INNER JOIN並且INNER JOIN前後不能使同一個表,不能使用LEFT(RIGHT) JOIN 或者 LEFT (RIGHT) OUTER JOIN ;看下面的例子:
比如說創建了下面的視圖(自鏈接):
CREATE VIEW dbo.vtUsers
WITH SCHEMABINDING
AS
SELECT dbo.tUsers.userid, dbo.tUsers.username, dbo.tUsers.password,
dbo.tUsers.question, dbo.tUsers.answer, dbo.tUsers.email, dbo.tUsers.realname
FROM dbo.tUsers Inner join
dbo.tUsers as t ON dbo.tUsers.userid = t.userid
這個視圖是可以創建的,但是在創建索引時CREATE UNIQUE CLUSTERED INDEX idxvtUser ON vtUsers(userid) 就會出錯了;
再看下面的視圖(外部連接):
CREATE VIEW dbo.vtUsers
WITH SCHEMABINDING
AS
SELECT dbo.tUsers.userid, dbo.tUsers.username, dbo.tUsers.password,
dbo.tUsers.question, dbo.tUsers.answer, dbo.tUsers.email, dbo.tUsers.realname
FROM dbo.tUsers LEFT OUTER JOIN
dbo.tUserInfo ON dbo.tUsers.userid = dbo.tUserInfo.userid
在創建索引時也會出錯的。
F. 視圖不能包含UNION子句、TOP子句、ORDER BY子句、Having子句、Rollup子句、Cube子句、compute子句、Compute By子句或Distinct關鍵字;
G. 視圖不允許使用某些集合函數,如:Count(*)可以使用count_big(*)代替、avg()、max()、min()、stdev()、stdevp()、var()或varp()等;
H. 視圖不能使用Select * 這樣的語句,也就是說視圖的所有字段都必須顯示指定;
I. 視圖不能包含Text、ntext、image類型的列;
J. 如果視圖包含一個Group By子句,那麼他必須在Select列中包含count_big(*);
K. 視圖中的所有標和用戶自定義的函數都必須使用兩段式名來引用,即所有者.表或函數名稱;
L. 所有的基本表和視圖都必須使用 Set Ansi_Nulls On 創建;
M. 在創建索引時或創建索引後執行IUD時,必須顯示或隱式地執行:
Set ANSI_NULLS ON
SET ANSI_PADDING ON
SET ANSI_WARNINGS ON
SET ARITHABORT ON
SET CONCAT_NULL_YIELDS_NULL ON
SET QUOTED_IDENTIFIER ON
SET NUMERIC_ROUNDABORT OFF
各個選項的有關信息或意義,可以查閱SQL Server的聯機叢書,這裏就不再介紹了;
N. 索引視圖只有在SQL Server2000的企業版或開發版或者更高的版本中才能創建。
如果一個視圖可以添加唯一聚集索引,那麼在添加了唯一聚集索引之後,該視圖也可以像數據庫表一樣添加非聚集索引,CREATE INDEX idxvtUsers ON vtUsers(username,realname)。
關於視圖大家可能還有更多好的處理方法和建議,希望大家補充。