对同一个表的列强制执行外键约束

pop*_*ack 10 sql oracle foreign-keys self-reference insert-into

在下表中输入值时,如何在SQL中对同一表的列强制执行外键约束:

员工:

  • empid数字,
  • 经理号码(必须是现有员工)

Ben*_*Ben 20

Oracle将此称为自引用完整性约束.文档在这里是为了描述,

您可以使用与普通约束相同的方式创建自引用约束:

alter table employees
  add constraint employees_emp_man_fk
      foreign key ( manager_no )
      references employees ( emp_id )
   on delete set null
      ;
Run Code Online (Sandbox Code Playgroud)

我假设你manager_no的可空.我在这里添加了set null,因为它delete cascade可能会消耗掉你的大量数据.

我想不出更好的方法.删除经理不应该导致所有员工被删除,因此您必须set null在桌面上触发并提醒任何没有经理的人.

我总是喜欢这个网站,这对简单的引用很有用.并且不要忘记在FK上有一个索引,否则汤姆会对你大喊:-).

还可以使用标准Oracle语法在create table语句中创建自引用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
 );
Run Code Online (Sandbox Code Playgroud)

编辑:

回答@popstack的评论如下:

虽然你可以在一个声明中做到这一点,但不能改变一个表是一种相当荒谬的事态.你肯定应该分析一个你要选择的表,你仍然需要一个外键索引(可能还有更多列和/或更多索引),否则每当你使用你要做的外键时全表扫描.请参阅上面的asktom链接.

如果您无法更改表格,则应按重要性降序排列.

  1. 了解如何做到.
  2. 更改你的数据库设计,因为FK应该有一个索引,如果你不能有一个,那么FK可能不是那样的.也许有一张经理人和一张员工表?

  • @Ben:如果在Oracle中没有指定"ON DELETE CASCADE"或"ON DELETE SET NULL",它将阻止您删除父级,这会通过抛出"ORA"来防止非显而易见的孤立记录-02292`. (2认同)

ins*_*ect -1

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
Run Code Online (Sandbox Code Playgroud)

希望能帮助到你!

  • 这对于 Oracle 来说不是一个有效的声明 (4认同)
  • @popstack 为什么你为 Oracle 问题选择仅 MySQL 的答案?您应该取消选择此答案并选择 Ben 的另一个答案。 (4认同)