我认为提议的设计要求是可疑的。我之前已经看到这种设计要求是由构建不良的对象模型进入构建不良的关系模型的。
尽管如此,如果要求是 active_card.num_card 必须引用两个表,则物化视图可以实现设计要求。
create table active_card(
num_id number primary key,
num_card number,
is_active varchar2(5) );
create table tmp_card(
num_card number primary key,
reg_date date );
create table definitive_card(
num_card number primary key,
name varchar(256),
create_date date );
create or replace view card_v as
select tc.num_card
from tmp_card tc
where exists ( select null
from definitive_card dc
where dc.num_card = tc.num_card );
alter table active_card
add constraint active_card_num_card_fk
foreign key (num_card)
references card_v (num_card); -- won't work
但是您不能针对视图创建外键...所以...创建一个物化视图:
create materialized view log on tmp_card;
create materialized view log on definitive_card;
create materialized view card_mv
build immediate
refresh fast
on commit
as
select tc.num_card
from tmp_card tc
where exists ( select null
from definitive_card dc
where dc.num_card = tc.num_card )
;
alter table active_card
add constraint active_card_num_card_fk
foreign key (num_card)
references card_mv (num_card); -- works
insert into tmp_card values ( 123, sysdate );
insert into tmp_card values ( 456, sysdate );
insert into tmp_card values ( 789, sysdate );
insert into definitive_card values ( 123, 'OneTwoThree', sysdate );
insert into definitive_card values ( 789, 'SevenEightNine', sysdate );
insert into definitive_card values ( 111, 'OneOneOne', sysdate );
commit;
现在...
insert into active_card values ( 1, 123, 'true' ); -- succeeds
insert into active_card values ( 1, 456, 'true' ); -- fails
insert into active_card values ( 1, 111, 'true' ); -- fails
delete from tmp_card where num_card = 789; -- succeeds
commit;
delete from tmp_card where num_card = 123; -- succeeds, but
commit; --fails
如果设计要求是 active_card.num_card 必须出现在两个表中的一个而不是两个表中,则需要调整物化视图定义。