假设我们有以下内容:
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_1
还是table_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函数同步。
我正在寻找一种更好的方法来做到这一点。
答案 0 :(得分: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;
/
答案 1 :(得分: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 :(得分: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的工资。