2013-06-20 2 views
3

У меня есть две родительские таблицы: Treatment и Visit.SQL. Как ссылаться на составной первичный ключ 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 table parent?

ответ

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, DateVisit, но внешний ключ от Visit_Treat только ссылки SlotNum.

У вас есть два хороших варианта:

  1. Добавить в DateVisit столбец Visit_Treat и имеют внешний ключ быть SlotNum, DateVisit, ссылаясь SlotNum, DateVisit в Visit.

  2. Создать первичный ключ нерабочих на Visit (например, столбец с именем VisitID типа NUMBER, питаемый последовательности), добавьте VisitID столбец Visit_Treat, и сделать это внешний ключ.

И два плохой вариант:

  1. Изменить первичный ключ Visit быть только SlotNum так что ваш Visit_Treat внешнего ключа будет работать. Это, вероятно, не то, что вы хотите.

  2. Не используйте внешний ключ. Я не рекомендую этот вариант. Если у вас возникли проблемы с настройкой внешнего ключа, который, как вы знаете, должен существовать, это обычно означает проблему с дизайном.

+0

Ваше первое предложение неверно. SQL FK ссылается на объявленный PK или UNIQUE NOT NULL. (Более или менее суперключ - и не обязательно минимальный/неприводимый, т. Е. CK.) Поскольку любой из них может содержать меньший или другой, FK должен ссылаться на все одно, но не обязательно все в частности, ПК.Вы как бы косвенно обращаетесь к этому в плохом варианте 1. Хотя «плохой вариант» кажется неправильным, поскольку это просто случай, когда дизайн неправильный, но FK прав. – philipxy

Смежные вопросы