[英]How to declare a foreign key with an OR condition using Oracle?
我有一个表(A),其主键是表(B)或表(C)的外键。
create table A (
akey number,
txt varchar2(10)
);
create table B (
bkey number,
txt varchar2(10)
);
create table C (
ckey number,
txt varchar2(10)
);
我想要的是:
alter table A add constraint BorCkey foreign key (akey) references B(bkey)` or C(ckey);
这可能吗?
外键约束是一个外表 。
这意味着在这种情况下你需要使用两个ALTER TABLE语句来设置外键来引用这两个表。 在那里没有机会在关系中指定OR - A.akey
的值必须同时存在于B.bkey
和 C.ckey
中 。 例如,如果B.bkey
的值为NULL,但C.ckey
没有 - 那么A.akey
的值永远不会为NULL。 外键在Oracle中是可延迟的,但所描述的行为是在同时启用两个外键时将遇到的行为 - 如果所有值都不满足关系,则无法启用约束。
您需要检查您对如何简化关系的需求,这样就不需要两个表来完成这项工作。
不,这种事情在Oracle中是不可能的。
您的选择通常是
如果需要一个约束,以确保两列中只有一列为NULL,而对于任何行,其中一列为NOT NULL
create table one_key(
col1 number,
col2 number,
check( nvl2(col1,1,0) + nvl2(col2,1,0) = 1 )
)
听起来你有某种形式的子类型/超类型关系。 一个典型的例子是'PERSON',它可以是'CUSTOMER'或'SUPPLIER'。
您可能在PERSON表中拥有PERSON_ID的唯一键以及PERSON_TYPE('CUST'或'SUPP')的属性。 如果在PERSON_ID,PERSON_TYPE上创建主键,则可以在子类型表(SUPPLIER / CUSTOMER)中引用该主键。
然后在person_id上添加一个唯一约束,以确保person_id的任何值必须是客户或供应商,而不是两者,并检查子类型表上的约束,以便表中只表示一种类型。
create table person
(person_id number,
person_type varchar2(4),
name varchar2(10),
constraint person_pk primary key (person_id, person_type),
constraint person_id_uk unique (person_id));
create table supplier
(supplier_id number,
supplier_type varchar2(4),
blah varchar2(10),
constraint supplier_pk primary key (supplier_id, supplier_type),
constraint supp_pers_fk foreign key (supplier_id, supplier_type)
REFERENCES person (person_id, person_type)
)
/
alter table supplier add constraint supp_type_ck check (supplier_type = 'SUPP');
它不漂亮但类型/子类型更多的是对象概念而不是关系概念。
我的解决方案受Justin的启发:
CREATE OR REPLACE TRIGGER abc
BEFORE INSERT OR UPDATE ON a
FOR EACH ROW
DECLARE
v_testB NUMBER:= 0;
v_testC NUMBER:= 0;
BEGIN
SELECT
COUNT(bkey)
INTO
v_testB
FROM
b
WHERE
bkey = :new.aKey;
SELECT
COUNT(ckey)
INTO
v_testC
FROM
c
WHERE
ckey = :new.aKey;
IF ((v_testB + v_testC) <> 1) THEN
RAISE_APPLICATION_ERROR(-20002,'Foreign key to B or C missing.');
END IF;
END;
/
SHOW ERRORS TRIGGER abc
创建一个实体化视图,用于联合表B&C,并将FK约束指向视图
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.