【问题标题】:Creating tables with circular reference使用循环引用创建表
【发布时间】:2013-09-16 16:07:39
【问题描述】:

如何创建具有循环引用的多个表。我想一次性创建这些数据:

DROP TABLE employee CASCADE CONSTRAINTS;
CREATE TABLE employee (
  fname    varchar2(15) not null, 
  minit    varchar2(1),
  lname    varchar2(15) not null,
  ssn      char(9),
  bdate    date,
  address  varchar2(30),
  sex      char,
  salary   number(10,2),
  superssn char(9),
  dno      number(4),
  primary key (ssn),
  foreign key (superssn) references employee(ssn),
  foreign key (dno) references department(dnumber)
);

DROP TABLE department CASCADE CONSTRAINTS;
CREATE TABLE department (
  dname        varchar2(15) not null,
  dnumber      number(4),
  mgrssn       char(9) not null, 
  mgrstartdate date,
  primary key (dnumber),
  unique (dname),
  foreign key (mgrssn) references employee(ssn)
);

DROP TABLE dept_locations CASCADE CONSTRAINTS;
CREATE TABLE dept_locations (
  dnumber   number(4),
  dlocation varchar2(15), 
  primary key (dnumber,dlocation),
  foreign key (dnumber) references department(dnumber)
);

DROP TABLE project CASCADE CONSTRAINTS;
CREATE TABLE project (
  pname      varchar2(15) not null,
  pnumber    number(4),
  plocation  varchar2(15),
  dnum       number(4) not null,
  primary key (pnumber),
  unique (pname),
  foreign key (dnum) references department(dnumber)
);

DROP TABLE works_on CASCADE CONSTRAINTS;
CREATE TABLE works_on (
  essn   char(9),
  pno    number(4),
  hours  number(4,1),
  primary key (essn,pno),
  foreign key (essn) references employee(ssn),
  foreign key (pno) references project(pnumber)
);

DROP TABLE dependent CASCADE CONSTRAINTS;
CREATE TABLE dependent (
  essn           char(9),
  dependent_name varchar2(15),
  sex            char,
  bdate          date,
  relationship   varchar2(8),
  primary key (essn,dependent_name),
  foreign key (essn) references employee(ssn)
);

请帮忙!!

【问题讨论】:

  • 有什么理由你不能运行这个?您收到错误代码了吗?
  • 不确定谁投票结束了这个问题而不发表评论,但我认为这是一个很好的问题。您可能需要重新考虑对 department.mgrssn 的非空约束。如果经理离开,他是否会 100% 立即更换?否则,您的数据模型不支持业务需求。
  • @DavidStarkey,代码不会运行,因为员工和部门表相互引用。
  • @DAn,谢谢你指出这一点。或许我们应该简化这个问题以专注于这个问题。

标签: sql oracle circular-reference


【解决方案1】:

您可以创建表,然后创建约束:

CREATE TABLE employee (
  fname    varchar2(15) not null, 
  minit    varchar2(1),
  lname    varchar2(15) not null,
  ssn      char(9),
  bdate    date,
  address  varchar2(30),
  sex      char,
  salary   number(10,2),
  superssn char(9),
  dno      number(4),
  primary key (ssn)
);

CREATE TABLE department (
  dname        varchar2(15) not null,
  dnumber      number(4),
  mgrssn       char(9) not null, 
  mgrstartdate date,
  primary key (dnumber),
  unique (dname)
);

ALTER TABLE employee ADD CONSTRAINT fk_dno FOREIGN KEY (dno) REFERENCES department(dnumber) DEFERRABLE;
ALTER TABLE department ADD CONSTRAINT fk_mgrssn FOREIGN KEY (mgrssn) REFERENCES employee(ssn) DEFERRABLE;

插入时,您可以将约束设置为延迟,这意味着 Oracle 在您提交之前不会验证它们。

ALTER SESSION SET CONSTRAINTS = DEFERRED;
insert into employee (fname, lname, ssn, dno) values ('Joe','Blow','123456789', 10);
insert into department(dname, dnumber, mgrssn) values ('Dept1',10, '123456789');
commit;

您也可以在创建它们时将它们设置为初始延迟,但约束必须至少是“可延迟的”才能执行上述操作。

【讨论】:

  • 在添加约束之前,请确保每个表中至少有一条记录。否则你会遇到相同问题的不同版本。
  • @DanBracuk 如果您最初将它们设置为延迟,则不是问题,请参阅我对答案的补充。
  • 你能确认这个答案吗?如果您发布答案,我会给您 chk。 dba.stackexchange.com/a/58959/32234
  • @Gracchus 嗨,您的问题与级联删除的行为有关(并且似乎适用于 PostgreSQL)。这个问题与使用延迟约束来完成插入有关。您是否尝试使用所需的级联删除设置一些测试表并尝试删除?我无权访问 PostgreSQL atm。
  • @tbone 感谢您观看 tbone!我希望这可能是我创建结构后的最后手段。我宁愿继续我的设计,也不愿测试是否可以得到答案,所以我想现在,我会等待答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-27
  • 2014-03-06
  • 2018-07-25
  • 1970-01-01
  • 2022-09-22
  • 1970-01-01
相关资源
最近更新 更多