2013-06-20 92 views
3

我有兩個父表:TreatmentVisitSQL。如何引用複合主鍵Oracle?

處理表:

create table Treatment (
    TreatCode CHAR(6) constraint cTreatCodeNN not null, 
    Name VARCHAR2(20), 
    constraint cTreatCodePK primary key (TreatCode), 
    ); 

訪問表:

create table Visit (
SlotNum NUMBER(2), 
DateVisit DATE, 
ActualArrivalTime DATE, 
constraint cVisitSlotDatePK primary key (SlotNum, DateVisit) 
); 

現在,我嘗試創建一個子表:

create table Visit_Treat (
TreatCode constraint cTreatCodeFK references Treatment(TreatCode), 
SlotNum constraint cSlotNumFK references Visit(SlotNum), 
DateVisit constraint cDateFK references Visit(DateVisit), 
constraint cVisitTreatPK primary key (SlotNum, TreatCode, DateVisit) 
); 

一切執行罰款,直到3號線。從第3行開始,即SlotNum constraint ...有一條消息:no matching unique or primary key。已經有一個similar question,但我沒有完全得到適用於我的情況的邏輯。我逐一引用每列,並且它適用於Treatment表父級。我應該如何更正表格父母的參考Visit

回答

7
CONSTRAINT fk_column 
FOREIGN KEY (column1, column2, ... column_n) 
REFERENCES parent_table (column1, column2, ... column_n) 

你的情況

create table Visit_Treat (
TreatCode CHAR(6) constraint cTreatCodeFK references Treatment(TreatCode), 
SlotNum NUMBER(2), 
DateVisit DATE, 
constraint cVisitTreatPK primary key (SlotNum, TreatCode, DateVisit), 
constraint fk_slotnumDatevisit FOREIGN KEY(SlotNum,DateVisit) 
references Visit(SlotNum,DateVisit) 
); 
+0

這可能也可能不是解決方案,因爲我們不知道什麼是對的,什麼是錯誤的代碼,它沒有解決什麼(組合)聲明應該用在什麼情況。 – philipxy

2

外鍵必須引用父表的主鍵 - 在整個主鍵。在你的情況下,Visit表的主鍵是SlotNum, DateVisitVisit_Treat外鍵只引用SlotNum

你有兩個不錯的選擇:

  1. 添加DateVisitVisit_Treat,並有外鍵是SlotNum, DateVisit,在Visit引用SlotNum, DateVisit

  2. 創建於Visit非營業主鍵(例如一個名爲NUMBERVisitID列來自一個序列),一個VisitID列添加到Visit_Treat,使外鍵。

和兩個糟糕的選擇:

  1. 更改Visit主鍵是唯一SlotNum所以你Visit_Treat外鍵會工作。這可能不是你想要的。

  2. 請勿使用外鍵。我不推薦這個選項。如果您在設置您認爲應該存在的外鍵時遇到問題,通常意味着設計問題。

+0

你的第一句話是不正確的。 SQL FK引用已聲明的PK或UNIQUE NOT NULL。 (或多或少是一個超級鍵 - 並不一定是最小/不可簡化的一個,即一個CK。)由於其中任何一個可能包含較小的一個或另一個,FK必須引用全部,但不一定全部特別的一個,包括一個PK。你有點間接地在不良選擇1中解決這個問題。儘管「不良選擇」似乎是不恰當的,因爲這只是設計錯誤但FK是正確的。 – philipxy