數據庫視圖是表的一個延伸對象。從理論上來說,在視圖上使用DML語句對數據進行更新,最終都會在基礎表上完成。也就是說,可以通過視圖對基礎表的內容進行修改。但是,往往沒有這麼簡單。若想在連接視圖上執行DML修改語句的話,需要嚴格的遵守一些限制。否則的話,DML語句不會執行成功。
假設現在人事管理系統中有三個表,一個是員工基本信息表,包含員工編號(非空)、員工姓名(非空)、身份證號碼等字段;第二個表是企業部門職位表包含職位編號(非空)、職位名稱(非空)、職位描述等字段;第三個是員工與部門職位對應表,包含員工編號(非空)、職位編號(非空)、描述等字段。
現在數據庫管理員做了一張視圖,查詢員工編號、員工姓名、部門信息。此時,這張連接視圖可以用DML語句來進行更新呢?這就要看其是否滿足一定的條件。
條件一:在連接視圖中不能有Order by排序語句。
若用戶想要在上面這張視圖中,更改員工所屬的部門,則首先要考慮,在生成視圖的查詢語句中,是否使用了Order by排序語句。若有這個排序語句的話,則在視圖上進行DML操作,是不會成功的。
這主要是因為采用了Order by排序語句後,記錄的物理存儲順序發生了改變。此時,若在視圖上進行了數據更新,則其對應的基礎表找不到具體更改的物理位置。所以,會以失敗告終。
所以,用戶若想在上面這個視圖界面對員工所屬的部門進行更改的話,則一定不能夠在SQL語句中加入Order by等排序語句。類似的,也不能夠在SQL語句中含有Group by、connetc by等語句。若有這些語句的話,則數據庫都不允許對數據進行數據更新操作。
條件二:基礎表中所有的NOT NULL列都必須在這個視圖中。
若想在視圖上進行數據更新操作的話,則必須要求對應基礎表中的所有不允許空的字段都在當前的視圖中。其實這很好理解,若每個字段不允許為空,則又不在當前的視圖中,則新增加記錄的時候,這個字段就沒有被賦值,故在保存時就會被基礎表所拒絕。
在上面這個例子中,數據庫管理員若建立的視圖沒有包含所有的非空字段。如企業部門職位表總的職位編號就沒有在這個視圖中。所以,數據庫不會接納這張視圖上的更新。若用戶確實需要在這張視圖上更新數據,則就要考慮把所有的非空字段顯示在這張視圖上。
另外,需要注意的是,無論是更新還是刪除語句,若基礎表中的某個非空列不在這個視圖中,都無法進行更改。也許有人會問,如果用戶不是增加記錄,而只是更新數據。那難道也要求在視圖中包含所有的非空字段呢?答案是肯定的。因為數據庫系統在提交更新事務之前就會對這個條件進行判斷。
條件三:需要更新的列不是虛擬列。
在視圖中,可能有些列的結果是通過列表達式定義的,在基礎表中並不存在。我們把這些列叫做虛擬列。如在上面的員工信息表中,並沒有員工的出生年月信息。而在視圖中,我們可以通過身份證號碼來取得某個員工的出生日期。此時若想在視圖中更改這個出生日期,則很明顯是不行的。因為基礎表中根本沒有這個字段,那更改的結果就無法保存。
只要在視圖中有虛擬列的存在,只要視圖中任何一列是由列表達式定義的,那麼對不起,整張視圖都不能夠進行更改。這個控制原理跟上面這個條件是類似的。
可見,在數據庫設計的時候,就需要考慮是否需要在視圖基礎上對表的內容進行更改。若需要更改的話,則一定不能夠在視圖中采用虛擬列,而寧願在表中多增加一些字段。或者在數據庫視圖中不采用虛擬列,而是在前台應用程序中采用虛擬列。
條件四:不能夠具有分組函數。
如上面這張員工與職位的對應關系表中,用戶不但想知道某個職位現有的員工有哪些;還希望知道,某個職位現在員工的具體人數。要實現這個需求的話,則數據庫管理員就需要在視圖中采用分組函數,來統計某個職位的具體人數。
但是,若視圖中有這個函數的話,則也不能夠對這張視圖進行更新。這是Oracle數據庫的強制規定。
其實,這也可以通過一些靈活的方式來避免。如在數據庫視圖中不需要采用分組函數。而是在前台的Select語句中,查用分組函數。因為前台要調用數據庫中的數據,仍然需要查用Select語句去查詢視圖。所以,即使在原始的數據庫視圖中不對數據進行分組,則在前台應用程序中仍然可以幫助用戶完成數據分組與統計的任務。此時,用戶若在視圖中更改數據的話,不僅可以更新數據庫基礎表中的內容;而且,還可以及時的反饋到前台的應用程序界面中。
分組函數會增加數據庫查詢的負擔;同時,使得無法在視圖上采取DML操作。故數據庫管理人員需要跟前台應用程序開發人員進行協商,在前台實現對數據的分組統計,而不是在後台。
除了以上幾個限制條件之外,若需要在視圖上進行DML操作的話,則在建立視圖的Select語句中,還不能夠有集合運算符、子查詢等等。以上這些是一些必須要滿足的基本條件,缺一不可。否則的話,針對視圖的DML操作,就會以失敗告終。
但是,並不是說符合了上面這個幾個條件後,視圖就可以暢所無阻的進行數據更新了,其仍然必須符合一定的規則。這其中,最重要的就是鍵值保存表規則。
如果連接視圖中的一個基礎表的鍵在他的視圖中仍然存在,並且在連接視圖中仍然是主鍵,則這個基礎表就為鍵值保存表。在連接視圖上,對視圖進行插入、刪除、更新等操作時,一次只能夠對視圖中的一個鍵值保存表進行更新。