Oracle資料庫物件_視圖
視圖是一種非常重要的資料庫物件,它的形式類似於普通表,我們可以從視圖中查詢資料。
實際上它是建立在表上的一種虛表,在視圖中並不儲存真正的資料,而是僅僅儲存一條SELECT語句,對視圖的訪問將被轉化為對錶的訪問。
視圖所基於的表稱為基表,而視圖可以認為是對基表的一種查詢操作。
使用視圖的主要目的是為了方便使用者訪問基表,以及保證使用者對基表的安全訪問。
對使用者而言,往往要對一個表進行大量的查詢操作,如果查詢操作比較複雜,並且需要頻繁地進行,那麼可以為這個查詢定義一個視圖。
需要注意的是,在視圖中並不儲存對基表的查詢結果,而僅僅儲存一條SELECT語句。
只有當訪問視圖時,資料庫伺服器才去執行視圖中的SELECT語句,從基表中查詢資料。
雖然我們對視圖沒有做過任何修改,但是對視圖的多次訪問可能得到不同的結果,因為基表中的資料可能隨時被修改。
所以視圖中並不儲存靜態資料,而是從基表中動態查詢的。
從另外一個角度來看,視圖可以保證對基表的安全訪問。
在設計表時,我們一般是從整體的角度來考慮表的結構的,而不是從每個使用者的角度來確定表結構以及定義允許的操作。
對於同一個表,不同的使用者可以進行不同的操作,可以訪問不同的資料。
這樣我們就可以為不同的使用者定義不同的視圖,從而保證使用者只能進行允許的操作,訪問特定的資料。
視圖的建立、修改和刪除
使用者可以在自己的模式中建立視圖,只要具有CREATE VIEW這個系統許可權即可。
如果希望在其他使用者的模式中建立視圖, 則需要具有CREATE ANY VIEW 系統許可權。
如果一個視圖的基表是其他使用者模式中的對象,那麼目前使用者需要具有對這個基表的SELECT許可權。
建立視圖的命令是CREATE VIEW ,這條命令的格式為:
CREATE OR REPLACE 視圖名稱
AS SELECT 語句
WITH READ ONLY
WITH CHECK OPTION;
其中最後兩個選項是可選的,其中“WITH READ ONLY”限定對視圖只能進行查詢操作,不能進行DML操作。
“ WITH CHECK OPTION”限定DML操作必須滿足一定的條件。
視圖被建立之後,可以通過DESC 命令查看視圖的結構。
查看視圖結構的方法與查看錶的方法相同,查看的結果是列出視圖中各列的定義。
視圖的結構是在執行CREATE VIEW語句建立視圖時確定的,在預設情況下,列的名稱與SELECT之後基表的列名相同,資料類型和是否為空白也繼承了基表中的相應列。
如果希望視圖中的各列使用不同的名字,那麼在建立視圖時,在視圖的名稱之後應該指定各列的名稱。
視圖作為一種資料庫物件,它的相關資訊被儲存在資料字典中。
與目前使用者的視圖有關的資料字典是USER_VIEWS ,查詢這個資料字典,可以獲得目前使用者的視圖的相關資訊。
資料字典視圖USER_VIEWS 各列的定義及其意義如下:
名稱 意義
VIEW_NAME Name of the view
TEXT_LENGTH Length of the view text
TEXT View text
TYPE_TEXT_LENGTH Length of the type clause of the object view
TYPE_TEXT Type clause of the object view
OID_TEXT_LENGTH Length of the WITH OBJECT OID clause of the object view
OID_TEXT WITH OBJECT OID clause of the object view
VIEW_TYPE_OWNER Owner of the type of the view if the view is a object view
VIEW_TYPE Type of the view if the view is a object view
SUPERVIEW_NAME Name of the superview, if view is a subview
EDITIONING_VIEW An indicator of whether the view is an Editioning View
READ_ONLY An indicator of whether the view is a Read Only View
註:indicator 指示符。
在列TEXT 中儲存的是建立視圖時使用的SELECT語句。
另外,在資料字典ALL_ VIEWS 儲存的是目前使用者可以訪問的所有視圖的資訊,在資料字典DBA_VIEWS儲存的是系統中的所有視圖的資訊,這個資料字典只有DBA可以訪問。
如果發現視圖的定義不合適,可以對其進行修改。
實際上視圖中的SELECT語句是不能直接修改的,所以修改視圖的一種方陸是先刪除視圖,再重新建立,另一種方怯是在建立視圖的CREATE語句中使用OR REPLACE選項。
視圖在不需要時,可以將其從資料庫中刪除。
刪除視圖的命令是DROP VIEW 。
使用者可以直接刪除自己建立的視圖,如果希望刪除其他使用者建立的視圖,則需要具有DROP ANY VIEW這個系統許可權。
DROP VIEW命令的格式為:
DROP VIEW 視圖名稱;
視圖被刪除後,相關的資訊也被從資料字典中刪除。
如何對視圖進行訪問
對視圖的訪問包括查詢和受限制的DML操作。
訪問視圖的方法與訪問表的方法基本相同。
在訪問視圖時,這種訪問被轉化為對基表的訪問,所以在視圖上執行DML操作時,也要遵守基表上的約束。
複雜視圖
以前在建立視圖時,在CREATE VIEW語句的SELECT子句中只涉及一個表的操作,並且只是對基表中的列進行簡單的查詢,並沒有出現多個基表,或者對基表中的列進行運算式運算或者函數運算的情況,這種視圖被稱為簡單視圖。
對簡單視圖不僅可以進行查詢操作,還可以進行DML操作。
複雜視圖是這樣的視圖,視圖中的列是從基表中的列經過運算式或函數運算而來,或者是對基表進行了DISTINCT查詢,或者、涉及多個表的操作。
總而言之,如果在用CREATE VIEW語句建立視圖時,在SELECT之後的列名中使用了運算式、函數,或者使用了DISTINCT關鍵字,或者對多個表進行了串連查詢,這樣的視圖都是複雜視圖。
建立複雜視圖仍然是通過執行CREATE VIEW命令完成的,只不過因為在SELECT子句中使用了運算式或者函數,這樣的運算式不能作為視圖中的列名,所以在建立複雜視圖時必須為每個列指定列名。
對複雜視圖,允許的操作只有查詢,大部分視圖不允許DML操作。
現在我們總結一下在什麼樣的視圖上可以執行DML操作,在什麼樣的視圖不允許執行DML操作。
對於簡單視圖,如果基表中的所有列都被包含在視圖中,或者至少主鍵列和所有不允許為空白的列都被包含在視圖中,並且在建立視圖的CREATE VIEW語句的SELECT語句中最多隻使用了WHERE子句,對這樣的視圖是可以進行插入、刪除、修改操作的。
如果在建立這樣的簡單視圖時使用了WITH CHECK OPTION選項,那麼執行DML操作時要遵守一定的約束條件。
對於涉及多個基表的複雜視圖,如果其中至少一個表的所有列都被包含在視圖中,或者至少一個表的主鍵列和所有不允許為空白的列都被包含在視圖中,並且在建立視圖的CREATEVIEW語句的SELECT語句中最多隻使用了WHERE子句,這樣的視圖是允許進行插入、刪除、修改操作的。
對這樣的視圖進行DML操作時,只有其中一個表可以被修改,並且被修改的列只能映射到一個表中。
對於只涉及一個基表的複雜視圖,如果視圖中的列是對基表的列經過某種運算而來,包括運算式、AVG 等函數,或者在建立視圖的CREATE VIEW 語句的SELECT語句中使用了DISTINCT關鍵字、GROUP子句,對這樣的視圖是不能進行DML操作的。
對於涉及多個表的視圖,如果視圖中的列沒有包含其中一個表中的所有主鍵列和所有不為空白的列,或者視圖中的部分列是經過對基表中的列經過某種運算而來的,或者在建立視圖時在SELECT子句中使用了DISTINCT關鍵字、GROUP子句,這樣的視圖也是不能進行DML操作的。