列值必须存在于另一个表的非主列中

时间:2016-04-24 06:40:52

标签: sql oracle

假设我有两个表:

TABLE_1

ID     AGE_T1     NAME
1       5         A
2      23         B
3       5         C
4       9         D

TABLE_2

AGE_T2     FREQUENCY
5           2
9           1
23          1

如何确保Age_t2值必须是Age_t1的值之一(Table1的非唯一列)。需要提及的是TABLE_1TABLE_2都是物理表(不是VIEW的任何逻辑结构)

注意:如果Age_t1是主键,那么外键约束就足够Age_t2。如果没有更好的解决方案,我也有INSERT TRIGGER的计划。

2 个答案:

答案 0 :(得分:1)

创建一个实体化视图,仅包含TABLE_1中的不同年龄:

CREATE MATERIALIZED VIEW LOG ON TABLE_1
   WITH SEQUENCE, ROWID(AGE_T1)
   INCLUDING NEW VALUES;

CREATE MATERIALIZED VIEW TABLE_1_MV
   BUILD IMMEDIATE
   REFRESH FAST ON COMMIT
   AS SELECT DISTINCT AGE_T1
      FROM   TABLE_1;

ALTER TABLE TABLE_1_MV ADD CONSTRAINT t1_mv__age_t1__pk PRIMARY KEY ( AGE_T1 );

然后,您可以在FOREIGN KEY上添加TABLE_2作为主键引用此内容:

ALTER TABLE TABLE_2 ADD CONSTRAINT t2__age__fk FOREIGN KEY ( AGE_T2 )
  REFERENCES TABLE_1_MV ( AGE_T1 );

答案 1 :(得分:0)

我认为这应该有效。 未经过测试。

它也基于物化观点; MV必须在提交时刷新,如MT0的解决方案。让MV只选择违反查找条件的行 - 并让MV的检查条件总是计算为FALSE,这样如果违反了原始查找条件,它将始终拒绝插入/更新/删除。如果需要,您可以使“始终为假”的约束可以推迟。

这样你只需要一个MV,你就不需要维护任何东西了。

create materialized view TABLE_2_MV
   build immediate
   refresh fast on commit
   as select age_t2
      from   table_2
      where  age_t2 not in (select age_t1 from table_1);
alter table TABLE_2_MV add constraint t2_mv_chk (0 != 0);
祝你好运!