視圖簡介:
視圖可以看作定義在SQL Server上的虛擬表。視圖正如其名字的含義一樣,是另一種查看數據的入口。
常規視圖本身並不存儲實際的數據,而僅僅是由SELECT語句組成的查詢定義的虛擬表 。
從數據庫系統內部來看,視圖是由一張或多張表中的數據組成的,從數據庫系統外部來看,視圖就如同一張表一樣,對表能夠進行的一般操作都可以應用於視圖。
例如查詢,插入,修改,刪除操作等,但插入、修改、刪除等的操作其實對於原始數據表的操作。
視圖的作用:
1、視圖隱藏了底層的表結構,簡化了數據訪問操作,客戶端不再需要知道底層表的結構及其之間的關系。
2、視圖提供了一個統一訪問數據的接口。(即可以允許用戶通過視圖訪問數據的安全機制,而不授予用戶直接訪問底層表的權限)
3、從而加強了安全性,使用戶只能看到視圖所顯示的數據。
4、視圖還可以被嵌套,一個視圖中可以嵌套另一個視圖。
語法:
1 CREATE [ OR ALTER ] VIEW [ schema_name . ] view_name [ (column [ ,...n ] ) ] 2 [ WITH <view_attribute> [ ,...n ] ] 3 AS select_statement 4 [ WITH CHECK OPTION ] 5 [ ; ] 6 7 <view_attribute> ::= 8 { 9 [ ENCRYPTION ] 10 [ SCHEMABINDING ] 11 [ VIEW_METADATA ] 12 } 13 <select_statement> ::= 14 [ WITH <common_table_expression> [ ,...n ] ] 15 SELECT <select_criteria>
參數:
schema_name:是視圖所有者的名稱,一般為 dbo。(指定視圖所有者名稱是可選的。)
view_name:是視圖的名稱。
column:是視圖中用於列的名稱。僅當列從算術表達式,函數或常數派生時,才需要列名稱; 當兩個或多個列可能具有相同的名稱時,通常是因為連接; 或者當視圖中的列被指定與其派生的列的名稱不同的名稱時。列名也可以在 SELECT 語句中分配。如果列未指定,則視圖列獲得相同的名稱作為 SELECT 語句中的列。
AS:指定視圖要執行的操作。
select_statement:是定義視圖的 SELECT 語句。該語句可以使用多個表和其他視圖。需要適當的權限才能從創建的視圖的 SELECT 子句中引用的對象進行選擇。
ENCRYPTION:對加密進行加密,加密之后不可修改。使用 WITH ENCRYPTION 可以防止將視圖作為 SQL Server 復制的一部分進行發布。
SCHEMABINDING:將視圖綁定到底層所應用到的表。指定 SCHEMABINDING 時,不能以影響視圖定義的方式修改表。必須首先修改或刪除視圖定義,以刪除要修改的表的依賴關系。使用 SCHEMABINDING 子句創建的視圖的視圖或表不能刪除,除非該視圖被刪除或更改,以使其不再具有綁定。
VIEW_METADATA:當使用 WITH VIEW_METADATA 創建視圖時,返回的是視圖的元數據,否則返回的元數據是視圖所引用表的元數據。
普通視圖:
1 --判斷用戶自定義視圖是否存在 2 if exists(select * from sysobjects where id=OBJECT_ID(N'v_Stu_Cou') and objectproperty(id,N'IsView')=1) 3 drop view v_Stu_Cou --刪除視圖 4 go 5 create view dbo.v_Stu_Cou --創建視圖 6 as 7 select S_Id,S_StuNo,S_Name,S_Sex,S_Height,S_BirthDate,c.C_Id,c.C_Name 8 from Student s 9 left join Course c on s.C_S_Id=c.C_Id 10 where s.C_S_Id is not null 11 go 12 13 14 select * from v_Stu_Cou --使用視圖查詢
索引視圖:
1 --判斷用戶自定義視圖是否存在 2 if exists(select * from sysobjects where id=OBJECT_ID(N'v_Stu_Cou_Index') and objectproperty(id,N'IsView')=1) 3 drop view v_Stu_Cou_Index --刪除視圖 4 go 5 create view dbo.v_Stu_Cou_Index --創建視圖 6 with schemabinding --指定架構綁定 7 as 8 select S_Id,S_StuNo,S_Name,S_Sex,S_Height,S_BirthDate,c.C_Id,c.C_Name 9 from dbo.Student s 10 inner join dbo.Course c on s.C_S_Id=c.C_Id 11 where s.C_S_Id is not null 12 go 13 14 --在視圖 v_Stu_Cou_Index 上建立唯一的聚集索引 15 create unique clustered index Index_View on v_Stu_Cou_Index(S_StuNo) 16 17 select * from v_Stu_Cou_Index --使用視圖查詢
PS:索引視圖涉及的基本表必須ANSI_NULLS設置為ON。索引視圖必須設置 ANSI_NULLS 和 QUOTED_INDETIFIER 為 ON。索引視圖只能引用基本表。(即不能嵌套視圖)
必須使用 WITH SCHEMABINDING 綁定架構。定義索引視圖時必須使用 Schema.ViewName 這樣的全名。(即需要指定視圖的所有者)
定義索引視圖的表也必須指定所有者,例如:dbo。
定義索引視圖不能使用外連接。(即 left join/left outer join、right join/right outer join、outer join/full outer join)
分區視圖:
分區視圖是由 UNION ALL 的所有成員表定義的視圖,即擁有相同的表結構、字段、數據類型等,不相同的數據集。
分區視圖又分為 本地式分區視圖和分布式分區視圖,我的理解就是本地式分區視圖就是同一個數據庫存在相同的表結構、字段、數據類型等的表使用 UNION ALL 創建的視圖;
分布式分區視圖就是數據源存在於不同的數據庫或不同的數據庫服務器使用 UNION ALL 創建的視圖。
1 --判斷用戶自定義視圖是否存在 2 if exists(select * from sysobjects where id=OBJECT_ID(N'v_Stu_Cou_Par') and objectproperty(id,N'IsView')=1) 3 drop view v_Stu_Cou_Par --刪除視圖 4 go 5 create view dbo.v_Stu_Cou_Par --創建視圖 6 as 7 select S_Id,S_StuNo,S_Name,S_Sex,S_Height,S_BirthDate,c.C_Id,c.C_Name 8 from Student s1 9 left join Course c on s1.C_S_Id=c.C_Id 10 where s1.C_S_Id is not null 11 12 union all 13 14 select S_Id,S_StuNo,S_Name,S_Sex,S_Height,S_BirthDate,c.C_Id,c.C_Name 15 from Student_back s2 16 left join Course c on s2.C_S_Id=c.C_Id 17 where s2.C_S_Id is not null 18 go 19 20 select * from v_Stu_Cou_Par --使用視圖查詢
當底層表的數據發生改變是,使用 sql 系統存儲過程 sp_refreshview 更新視圖數據。
1 exec sp_refreshview 'v_Stu_Cou_Par' -- v_Stu_Cou_Par 視圖名稱
使用 sql 系統存儲過程 sp_helptext 獲取自定義視圖創建的 T-SQL 文本。
1 exec sp_helptext 'v_Stu_Cou_Par' -- v_Stu_Cou_Par 視圖名稱
PS:視圖不能包含 ORDER BY 子句,除非SELECT語句的選擇列表中還有一個 TOP 子句。
視圖不能使用 INTO 關鍵字。視圖不能包含 OPTION 子句。
視圖不能有對臨時表或表變量的引用。視圖最多可以有 1024 列。
參考:
http://www.cnblogs.com/CareySon/archive/2011/12/07/2279522.html
https://docs.microsoft.com/en-us/sql/t-sql/statements/create-view-transact-sql