可更新視圖的說明

Oracle是一個適用於大中型企業、功能強大且較爲複雜的對象-關係型數據庫管理系統,它在銀行、電信、航空、保險、證券等領域都有着非常廣泛的應用。在Oracle數據庫的應用當中,經常需要涉及到對視圖的操作。Oracle對視圖的查詢操作沒有任何的限制,但是對視圖的更新操作往往受到一定的約束。下面介紹如何實現對Oracle可更新視圖的設計。
  
  1 視圖的概念
  視圖(View)是從一個或多個基表(或視圖)中導出的表,是一個查詢定義,也可認爲是一個存儲的查詢(Stored Query)或是一個虛表(Virtual Table)。視圖不同於表,一個視圖不分配任何存儲空間,不真正地包含數據,視圖只在數據字典中存儲其定義。視圖是數據庫開發中應用非常廣泛的一種數據庫對象。由於它具有限制數據訪問、簡化查詢、提供獨立數據、允許多個視圖使用相同數據、刪除視圖時不影響基表等特點,使得我們在開發數據庫應用時,降低了數據操作的複雜性、減少了數據層和應用層之間的耦合,最終提高了開發效率。
  可更新視圖是指可以進行插入、修改和刪除數據操作的視圖。Oracle對視圖的更新操作有一定的限制,在Oracle數據庫中,基於單個基表的視圖是可更新的,但對於多表聯合的視圖,由於它的複雜性,往往受到一定的限制。本文以一個簡單的例子說明了視圖的基本設計方法,並分析了在Oracle數據庫中如何實現對視圖的更新。
  建立兩個表students和teachers結構。
  其中students表1中的t_id爲任課教師編號,與teachers中t_id相關聯,在做多表連接時可以認爲teachers表爲主表(即連接表),students表爲從表(被連接表)。下面以 students 表和teachers表爲例,設計實現了單表視圖 s_view1和多表視圖s_view2。
  
  2 單表視圖的設計
  若一個視圖是從單個基表導出的,並且只是去掉了基表的某些行和列,且保留了基表的主碼,這樣的視圖被稱爲行列子集視圖,又稱爲單表視圖。創建單表視圖的方法如下:
  create view s_view1 as select s_id, s_name, s_sex from students;
  創建的視圖 s_view1 只涉及到一張表students,並且只是這張表的一部分,將一些不必要的數據隱藏起來,使得部分數據對用戶是透明的,增強了系統的安全性。這種方法創建出來的視圖是可更新視圖,如果在創建視圖時加上with read only子句,將其創建爲只讀視圖,則視圖即爲不可更新。
  
  3 多表視圖的設計
  3.1 主鍵連接方式
  若一個視圖是從多個基表中導出,滿足一定的連接條件,這樣的視圖就是多表聯合視圖。Oracle數據庫中多表視圖的更新操作受到了一定的限制,普通的無主鍵連接將不能進行視圖的更新操作,只有主表爲鍵值保存表,並且連接條件中包含主表的主鍵列時,才能夠實現視圖非主表列的更新創建方法爲:
  alter table teachers add primary key(t_id);
  create view s_view2 as select s.s_id,s.s_name,t.t_name,t.t_course from students s,teachers t where s.t_id=t.t_id;
  如果主表無主鍵列、主鍵列沒有當作連接條件或是更新主表列時都將提示錯誤。
  用上述方法創建的多表視圖,並不是所有的列都可更新,只有非主表的列(即 s_id,s_name)纔可以進行更新操作,如果想知道視圖中具體哪一列可以更新,可以通過查看SYS方案中DBA_UPDATABLE_COLUMNS視圖得到相關信息。
  從上面可以看出,這種創建可更新視圖的方法還是有一定侷限性的,不能對主表列進行更新操作。本文采用Oracle數據庫提供的 instead of 觸發器能夠很好的解決這一問題。
  3.2 觸發器方式
  觸發器(Database Trigger)是存儲在數據庫中的過程,當表或視圖被修改時它隱式地被執行。在Oracle中允許在對錶或視圖發出Insert、Update或Delete語句時隱式地執行所定義的過程,這些過程稱爲數據庫觸發器。
  創建觸發器的語法如下:
  CREATE [OR REPLACE] TRIGGER trigger_name [BEFORE|AFTER|INSTEAD OF] event
  ON table_or_view_name [FOR EACH ROW[WHEN condition]]
  Oracle數據庫中提供了一種INSTEAD OF觸發器,對於包含多個基表的視圖,可以通過使用INSTEAD OF觸發器來支持基表中數據的插入、更新和刪除操作。INSTEAD OF觸發器的實質就是阻止Oracle去嘗試解釋更新操作的視圖定義,而是使Oracle執行該觸發器的主體,依靠觸發器的定義來得出有意義的語義。INSTEAD OF觸發器總是爲視圖而創建的,它始終是FOR EACH ROW觸發器,這意味着針對每個可以對視圖進行刪除、更新或插入操作的行,都要執行一次這個觸發器。使用INSEAD OF觸發器的主要優點就是可以使不能更新的視圖支持更新,從而擴大了視圖的應用範圍,對視圖的操作更加直接、方便。該觸發器中轉換表和轉換變量的概念與普通觸發器中的概念一致。
  下面以s_view2爲例採用INSTEAD OF方式創建update觸發器如下:
  create or replace trigger s_tri instead of update on s_view2 for each row
  begin
  update teachers set t_name=:new.t_name,t_course=:new.t_course
  where t_name=:old.t_name;
  update students set s_id=:new.s_id,s_name=:new.s_name
  where s_id=:old.s_id;
  end;
  用上述方法創建的觸發器直接作用在視圖s_view2上,當對視圖進行update操作時,將自動轉去執行觸發器s_tri,該觸發器能夠根據不同的sql語句對視圖的所有列s_id,s_name,t_name和t_course都可以進行 update操作,彌補了普通主鍵連接方式只能修改從表的缺陷。Insert觸發器和delete觸發器的設計方法與上述update觸發器的設計方法相似
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章