[英]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.