Приложете ограничение за външен ключ към колони на същата таблица

Как да наложа ограничение на външен ключ върху колони на една и съща таблица в SQL, докато въвеждате стойности в следната таблица:

служител:

  • емпидно число,
  • мениджърски номер (трябва да е съществуващ служител)

person pop stack    schedule 07.01.2012    source източник


Отговори (3)


CREATE TABLE TABLE_NAME (
    `empid_number`    int     (  11) NOT NULL auto_increment,   
    `employee`        varchar ( 100) NOT NULL               ,
    `manager_number`  int     (  11) NOT NULL               ,
     PRIMARY KEY  (`empid_number`),
     CONSTRAINT `manager_references_employee`
     FOREIGN KEY (`manager_number`) REFERENCES (`empid_number`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

Дано помогне!

person instanceOfObject    schedule 07.01.2012
comment
до известна степен...! Някакви други методи/предложения за oracle? - person pop stack; 07.01.2012
comment
Никога не съм опитвал, но мисля, че даването на TABLE_NAME вместо parent_table_name трябва да работи!! - person instanceOfObject; 07.01.2012
comment
Това не е валидно твърдение за Oracle - person a_horse_with_no_name; 07.01.2012
comment
Предложих за MySql. Както казах, нямам представа за оракул. - person instanceOfObject; 07.01.2012
comment
@popstack защо избрахте отговор само за MySQL за въпрос на Oracle? Трябва да премахнете отметката от този отговор и да изберете другия отговор от Бен. - person Sled; 13.08.2013

Oracle нарича това ограничение за самореферентна цялост. Документацията е тук за описание,

Създавате самореферентно ограничение по същия начин, по който бихте направили нормално:

alter table employees
  add constraint employees_emp_man_fk
      foreign key ( manager_no )
      references employees ( emp_id )
   on delete set null
      ;

Предполагам, че вашият manager_no е nullable. Добавих set null тук, тъй като delete cascade вероятно ще унищожи значителна част от вашата таблица.

Не мога да измисля по-добър начин да направя това. Изтриването на мениджър не трябва да води до изтриването на всички негови служители, така че трябва да set null и да имате тригер на масата, който да ви предупреждава за всеки, който няма мениджър.

Винаги харесвам този сайт, който е добър за прости справки. и не забравяйте също да имате индекс във FK или Том ще ви крещи :-).

Човек може също да използва стандартен синтаксис на Oracle, за да създаде самореферентна FK в израза за създаване на таблица, който ще изглежда по следния начин.

create table employees
 ( emp_id number
 , other_columns ...
 , manager_no number
 , constraint employees_pk 
    primary key (emp_id)
 , constraint employees_man_emp_fk
    foreign key ( manager_no )
    references employees ( emp_id )
    on delete set null
 );

РЕДАКТИРАНЕ:

В отговор на коментара на @popstack по-долу:

Въпреки че можете да направите това с едно изявление, невъзможността да промените таблица е доста нелепо състояние на нещата. Определено трябва да анализирате таблица, от която ще избирате, и пак ще искате индекс на външния ключ (и евентуално повече колони и/или повече индекси), в противен случай, когато използвате външния ключ, ще правите пълно сканиране на масата. Вижте връзката ми към asktom по-горе.

Ако не можете да промените таблица, тогава трябва, в низходящ ред на важност.

  1. Разберете как можете.
  2. Променете дизайна на вашата DB, тъй като FK трябва да има индекс и ако не можете да имате такъв, FK вероятно не са правилният начин. Може би има таблица на мениджърите и маса на служителите?
person Ben    schedule 07.01.2012
comment
това може да е решение, НО в моя случай не се допускат никакви „тригери“, никакви „промени“. просто „създаване на таблица“, последвано от „вмъквания“, са необходими само. Сега? - person pop stack; 07.01.2012
comment
@popstack, имах твърде много да кажа, затова добавих редакция към отговора. - person Ben; 07.01.2012
comment
Доста сигурен, че ще трябва да дефинирате ограничение за уникален или външен ключ, за да може ограничението за външен ключ да се препраща. И винаги можете да пропуснете клаузата ON DELETE, която функционира като клауза ON DELETE RESTRICT в други RDBMS, предотвратявайки изтриването на родител с дъщерни записи. - person Adam Musch; 09.01.2012
comment
@AdamMusch, ти разбира се прав за PK. Актуализирах отговора. Все пак не ми харесва да не правя нищо след изтриване; ако не го направите, това не предоставя предимства над set null и ще ви остави с неочевидно осиротели записи в таблицата. - person Ben; 09.01.2012
comment
@Ben: Ако не посочите нито ON DELETE CASCADE, нито ON DELETE SET NULL в Oracle, това ще ви попречи да изтриете родителя, което предотвратява неочевидно осиротелите записи на първо място чрез хвърляне на ORA-02292. - person Adam Musch; 09.01.2012

ЗАПИТВАНЕ ЗА САМОРЕФЕРЕНЦИИ...

Alter table table_name ADD constraints constraints_name foreign key(column_name1,column_name2..) references table_name(column_name1,column_name2...) ON DELETE CASCADE;

EX- ALTER TABLE Employee ADD CONSTRAINTS Fr_key( mgr_no) references employee(Emp_no) ON DELETE CASCADE;

person pawan kumar    schedule 13.08.2013