2011-06-30 48 views
4

比方說,我們有以下幾點:更新視圖(Oracle)的

create view view_1 as 
(
    select key, data from some_table_or_view; 
); 

create table table_1 
(
    key 
    more_data 
); 

create view view_2 as 
(
    select v1.key, v1.data, t1.more_data 
    from view_1 v1, table_1 t1 
    where v1.key = t1.key 
); 

create table table_2 as 
(
    key 
    data 
    more_data 
); 

create view view_3 as 
(
    select key, data, more_data from view_2 
    union 
    select key, data, more_data from table_2 
); 

所以基本上,我們已經加入了兩個數據源,一個是來自於加入,一個是原始數據。

我希望能夠做到以下幾點。

update view_3 set more_data = 'BLAH_MORE_DATA' where key = 'BLAH_KEY'; 

如果這在某種程度上既更新或table_1根據table_2是否 「BLAH_KEY」 來自table_1table_2

目前我能想到的唯一的辦法就是:

create view view_3 as 
(
    select 'TAB1' as source, key, data, more_data from view_2 
    union 
    select 'TAB2' as source, key, data, more_data from table_2 
); 

,然後做使用它檢查源列,並更新相應的表中的PL/SQL功能的更新,但是這意味着我必須保持查看和PL/SQL功能同步。

我正在尋找一種更好的方式來做到這一點。

+1

使用PL/SQL程序已經實現複雜邏輯的好方法:)我upvoted schurik的觸發答案,因爲它的工作原理,但我還是寧願程序的方法。 –

回答

7

您可以在view_3

CREATE OR REPLACE TRIGGER view3_trg 
INSTEAD OF UPDATE 
ON view_3 
FOR EACH ROW 
BEGIN 
IF :OLD.source = 'TAB1' THEN 

    UPDATE table_1 t1 
    set t1.data = :NEW.data 
    WHERE 
    t1.key = :OLD.key 
    ; 
ELSIF OLD.source = 'TAB2' THEN 
    UPDATE table_2 t2 
    set t2.data = :NEW.data 
    WHERE 
    t2.key = :OLD.key 
    ; 
END IF; 
END; 
/
2

使用的,而不是觸發適應schurik的回答,並考慮到你的意見 「否則,如果-迪斯海瑪病」:

CREATE OR REPLACE TRIGGER view3_trg 
INSTEAD OF UPDATE 
ON view_3 
FOR EACH ROW 
BEGIN 
    UPDATE table_1 t1 
    set t1.data = :NEW.data 
    WHERE t1.key = :OLD.key; 

    UPDATE table_2 t2 
    set t2.data = :NEW.data 
    WHERE t2.key = :OLD.key; 
END; 

/

2
create view view_2 as 
(
    select v1.key, v1.data, t1.more_data 
    from view_1 v1, table_1 t1 
    where v1.key = t1.key 
); 

View_2可能不會更新。或者至少只有強制外鍵關係中的子表的列。

檢查user_updatable_columns,看看哪一個視圖的列可以自動更新(即其中Oracle可以制定出列的更新永遠是模糊的)。例如,如果使用EMP和DEPT,如果SMITH和JONES爲同一部門工作,則無法單獨更新SMITH的部門名稱(因爲dept_name是父級的屬性),但可以更新SMITH的薪水。