Oracle视图(View)----------------数据库中虚拟的表
-
一、什么是視圖
?
1、認識視圖
根據官方的文檔可以這么理解視圖:它是一個基于一個表或多個表的邏輯表,視圖本身不包含任何數據。通俗來說,可以把視圖看成是虛擬的表,只是一個查詢語句的結果,它的數據最終是從表中獲取的,這些表通常稱為源表或基表。當基表的數據發生變化時,視圖里的數據同樣發生變化。通常視圖的數據源有下面三種情況:
- 單一表的子集
- 多表操作的結果集? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
- 視圖的子集
?
?
2、視圖的作用
■ 簡化數據。表中的很多數據對業務來說是冗余的,這時開發者會使用比較復雜的SQL語句得到自己想要的結果。但實際開發中不能要求每個人都能做到這一點,所以,通常情況下由一個人把該復雜語句做成視圖,其他人員直接調用該視圖即可。這樣對視圖的使用人員就簡化了數據,從而隱藏了數據的復雜性。
■ 使數據更加獨立。程序開發時,大多的設計是程序直接訪問數據庫的表,但當這些表的結構隨著業務的變化而不得不重新設計時會影響到程序(通常表一旦設計完成就很難再做修改),所以可以使得程序直接訪問視圖。這樣,通過視圖就可以把程序和數據庫的表隔離開來,降低開發者的勞動成本。
■ 增加安全性。使用視圖可以查詢表的指定列來展現給用戶,而不必讓使用者完全看見表中的所有字段。這種情況多見于一個公司提供給其他合作伙伴查詢數據的接口,而視圖通常也會設成只讀屬性。
?
3、視圖的語法
CREATE [ OR REPLACE ] [ [ NO ] FORCE ] VIEW[ schema. ]view[(alias,...) inline_constraint(s)][out_of_line_constraint(s)] AS subquery [WITH { READ ONLY | CHECK OPTION [ CONSTRAINT constraint ] } ];【語法說明】
■ OR REPLACE:表示新建視圖可以覆蓋同名視圖。
■ [ NO ] FORCE:即FORCE或NOFORCE,表示是否強制創建視圖。例如,在基表不存在的情況下就創建視圖是錯誤的,這時可以用FORCE關鍵字強制創建視圖,然后再創建基表。Oracle中NOFORCE是默認值。
■ [ schema. ]view:這是視圖的所屬模式的名稱和視圖本身的名稱。
■ [(alias,...) inline_constraint(s)]:視圖字段的別名和內聯約束。
■ [out_of_line_constraint(s)]:也是約束,是與inline_ constraint(s)相反的聲明方式。
■ WITH READ ONLY:設置視圖只讀特性,這樣的視圖具有更高的安全性。
■ WITH CHECK OPTION [ CONSTRAINT constraint ]:一旦使用該限制,當對視圖增加或修改數據時必須滿足子查詢的條件。也就是說,是把子查詢的條件作為一個約束,而constraint是這個約束的名稱。
注意?? ?語法中的大括號表示必選語法項,這里只是說明WITH后面必須接大括號里面的內容。
?
二、創建視圖
?
1.創建單表視圖
還是以PRODUCTINFO(產品信息表)和CATEGORYINFO(產品類型表)為基礎如圖:
注意 根據官方提供的資料,在當前用戶下創建視圖需要有CREATE VIEW系統權限,這里直接給當前用戶賦予了DBA權限。
?
【示例1】創建單表視圖
這個單表視圖的作用是展示5行產地為“中國”的數據。在SQL*Plus中編寫如下腳本并執行:
- 【代碼解析】
- 第1行表示創建或覆蓋名稱為SIMPLE_PRODUCTINFO_VIEW的視圖。如果沒有OR REPLACE 關鍵字,則表示只創建視圖而不能覆蓋同名視圖。
- 第5行表示只列出產地是“中國”的數據。
- 第6行中的ROWNUM < 6表示列出5條數據。ROWNUM是一個偽列,也就是說表中沒有該字段,利用它可以限制返回的行數。它總是從1開始增加,這個特點決定了使用它時通常都是用ROWNUM < n(n>1)或ROWNUM = 1的格式作為條件。
?
2、創建多表視圖
【示例2】創建多表視圖
下面創建的視圖是把PRODUCTINFO和CATEGORYINFO這兩個表關聯起來查詢的,目的是把商品類型編碼替換成商品類型。
【代碼解析】
- 第1行表示創建或覆蓋名稱為MULTI_PRODUCTINFO_VIEW的視圖。 ? ? ? ? ? ? ? ? ? ? ? ? ? ?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
- 第3行和第4行的字段前面多了“PT”或“CG”字樣,這是表的別名,這樣使讀者能夠直觀地了解到該字段屬于哪個表。
- 第4行的CG.CATEGORYNAME字段表示產品類型名稱。
- 第6行表示查詢數據的條件之一是把PRODUCTINFO表中CATEGORY字段和CATEGORYINFO表中CATEGORYID字段值相等的記錄關聯起來,以達到把商品類型編碼替換成商品類型的目的。
- 第7行和第8行腳本的詳細解釋參考“示例1”。
其實還可以創建視圖的視圖和沒有源表的視圖,但是日常使用較少,這里不過多介紹。
?
三、操作視圖數據的限制
視圖允許做DML操作,但需要注意的地方比較多。因為對視圖增加或更新數據實際上是在操作視圖的源表。除此之外,視圖本身可以設置更新的限制條件。本節主要介紹對視圖數據做更新操作的相關注意事項。
?
1、視圖的READ ONLY屬性設置
【示例3】創建只讀屬性的視圖-----------創建視圖時為了避免用戶修改數據,可以把視圖設成只讀屬性
01 CREATE OR REPLACE VIEW SIMPLE_PRODUCTINFO_VIEW AS 02 SELECT PRODUCTID, PRODUCTNAME, PRODUCTPRICE, CATEGORY, ORIGIN 03 FROM PRODUCTINFO 04 WHERE ORIGIN = '中國' 05 WITH READ ONLY【代碼解析】
■ 第5行是本小節的重點,通過這個選項可以設置該視圖只讀。當插入或修改視圖數據時,會提示“無法對只讀視圖執行DML操作”的信息。
?
2、視圖的CHECK OPTION屬性設置
CHECK OPTION選項表示視圖啟動了和子查詢條件一樣的約束。也就是說,如果對視圖進行修改或插入的數據與查詢條件不一致,那么該操作會被中止。
【示例4】創建帶檢查約束的視圖
01 CREATE OR REPLACE VIEW SIMPLE_PRODUCTINFO_VIEW AS 02 SELECT PRODUCTID, PRODUCTNAME, PRODUCTPRICE, CATEGORY, ORIGIN 03 FROM PRODUCTINFO 04 WHERE ORIGIN = '中國' 05 WITH CHECK OPTION【代碼解析】
■ 第5行表示開啟了條件檢查。這時如果要增加或修改數據,就要符合WHERE后面的條件,即ORIGIN字段的值是“中國”。
【執行效果】
以上腳本創建的視圖的數據要求只列出產地是中國的商品。查詢后列表如下圖所示。
為了驗證視圖的CHECK OPTION設置是否生效,下面在PL/SQL Developer工具中對視圖進行DML操作。
(1)增加數據
執行如下增加語句:
這里增加的數據的ORIGIN字段值是“美國”,它和視圖的查詢條件不一致,那么會出現錯誤提示,如下圖所示。
(2)修改數據
對視圖的某條記錄進行修改,執行如下語句:
以上腳本把視圖里產品編號為0240020001的數據的ORIGIN字段值修改為“美國”,但依然提示圖9-14所示的錯誤。
(3)刪除數據
在表PRODUCTINFO中有一條數據的ORIGIN字段的值是“美國”,接下來我們對視圖執行刪除操作。腳本如下:
腳本執行后并沒有出現錯誤提示,但會提示0行被操作。這不但說明視圖過濾出來的數據和源表的數據在邏輯上是徹底分離的,也說明了CHECK OPTION項對刪除操作不起作用(如果有作用,刪除語句將無法執行)。
3、? 視圖創建語句對視圖操作的影響
如果想要一個可以更新(這里的更新是指增加、刪除、修改)的視圖,則其源表盡量是單表,否則限制會比較多。下面的情況一旦出現在視圖中,視圖就不允許更新。
■ DISTINCT關鍵字。
■ 集合運算或分組函數。如INTERSECT、SUM、MAX、COUNT等函數。
■ 出現GROUP BY、ORDER BY、MODEL、START WITH等語句。
■ 出現偽列關鍵字,如ROWNUM。
除了以上情況外,還需要考慮基表的一些約束,這些約束對視圖數據的更新都有一定影響。如果需要創建可以更新的視圖,可以使用INSTEAD OF觸發器。
?
最后留給小伙伴們一個思考題:
當對視圖做刪除數據操作時,如果視圖里沒有符合條件的數據,但基表存在符合條件數據,實際會出現什么情況?
到此,視圖學習告一段落,歡迎糾正,歡迎補充。
本博客主要引自:《零基礎學Oracle》 — 趙雪 胡可 王建強
總結
以上是生活随笔為你收集整理的Oracle视图(View)----------------数据库中虚拟的表的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: .lib不是有效的Win32应用程序
- 下一篇: Graphics.DrawString