我有两张桌子:
Empleados(**numEmpl**, nombre, apellido, sexo, telefono, salario, numDept)
Departamentos(**numDept**, nombreDept, numDirect)
在出发中:
所以有一个循环引用。
首先我创建了表:
CREATE TABLE EMPLEADOS(numEmpl primary key, nombre,
apellido, sexo, telefono, salario, numDept)
CREATE TABLE DEPARTAMENTOS(numDept primary key, nombreDept, numDirect)
(i didn't write here each of type is each colum)
现在我在它们之间创建引用:
ALTER TABLE DEPARTAMENTOS
ADD CONSTRAINT FK_DEPT_EMP FOREIGN KEY (numDirect)
REFERENCES EMPLEADOS(numEmpl)
ALTER TABLE EMPLEADOS
ADD CONSTRAINT FK_EMP_DEPT FOREIGN KEY (numDept)
REFERENCES DEPARTAMENTOS(numDept).
它有效,所以现在我尝试插入一些数据:
INSERT INTO Empleados(numEmpl, nombre, apellidos, sexo, telefono, salario, numDept)
VALUES (1, 'Pepito', 'Pérez', 'H', '111111111', 20000, 1);
INSERT INTO Departamentos(numDept, nombreDept, numDirect)
VALUES (1, 'Direccion', 1);
但现在它抛出一个错误,告诉我我不能在循环引用中引入数据,我试图禁用循环引用并插入数据,然后再次启用它,它工作但有人告诉我它不是这是正确的方式,我必须做一些特别的事情,而我正在创建表格,以这种方式插入数据,它会工作,但我不知道如何做到这一点。 我顺便使用oracle sql developer。
编辑:谢谢你的答案,但他们没有奏效。首先,我只能拥有那些表,当我进行插入时,必须以这种方式工作,不要将参数设为null然后更新它,对不起,我之前没有说过。 所以我必须这样做的唯一方法就是允许圆圈参考,但是当我尝试按照有人在这里说的方式做的时候,它会告诉我一些关于回滚的事情,有人可以提供帮助吗?答案 0 :(得分:5)
要允许循环引用,您需要可延迟的约束:
ALTER TABLE DEPARTAMENTOS
ADD CONSTRAINT FK_DEPT_EMP FOREIGN KEY (numDirect)
REFERENCES EMPLEADOS(numEmpl)
DEFERRABLE INITIALLY DEFERRED
;
ALTER TABLE EMPLEADOS
ADD CONSTRAINT FK_EMP_DEPT FOREIGN KEY (numDept)
REFERENCES DEPARTAMENTOS(numDept)
DEFERRABLE INITIALLY DEFERRED
;
在交易结束时检查可延迟约束;在提交时间之前,允许存在虚假的无效数据库状态(在原始问题中:在两个插入语句之间)。但是语句必须在事务中,因此语句应该包含在BEGIN [WORK];
和COMMIT [WORK];
中。
答案 1 :(得分:0)
循环引用很危险,导致您需要返回并更新数据,以使其不处于不一致状态。
如果您正处于计划阶段,我仍然建议您先考虑其他选项以避免这种情况,否则您可能会遇到很多麻烦。
http://blogs.msdn.com/b/sqlazure/archive/2010/07/01/10033575.aspx
如果您确实希望仍然使用它们,那么我建议在departments表上将NULL设置为允许值(这允许您插入一个没有d的新值),插入员工,然后返回并更新与员工ID。
答案 2 :(得分:0)
发生这种情况是因为在您为该员工创建Employees表中的记录(numEmpl = 1)之前,您无法在Department表中为numDirect创建值为1的记录。在创建部门记录之前,您无法创建员工。这可以通过使过程三步而不是仅两步来解决。要做到这一点,你必须能够创建没有numDirect FK值的Department记录,或者你必须能够创建没有numDept FK值的Employee。
说你决定后者。在这种情况下,在表NumDept
中使EMPLEADOS
为Nullable:
Alter table EMPLEADOS Alter Column numDept null
然后你可以:
首先,添加numDept
INSERT Empleados(numEmpl, nombre, apellidos,
sexo, telefono, salario, numDept)
VALUES (1, 'Pepito', 'Pérez', 'H', '111111111', 20000, null);
第二,添加员工:
INSERT Departamentos(numDept, nombreDept, numDirect)
VALUES (1, 'Direccion', 1);
最后,在部门记录中更新numDept
的值。
Update Empleados Set numDept = 1
Where numEmpl = 1
答案 3 :(得分:-1)
从您的出租表中取出numDirect列。该表应简单描述该部门。根据您的业务规则,您希望您拥有的离开和Empleados之间存在一对多的关系,或者它们之间存在多对多的关系。如果Empleado可以用于多个离开,那么您希望从Empleados表中删除numDept列并创建另一个表来设置多对多关系。
如果您设法找出使用当前设计添加记录的方法,那么您将遇到更大的问题。而不是只为每个部分记录一个记录,而是每个部分都需要一个记录。