在具有循环引用的表中插入SQL
我有两张桌子:在具有循环引用的表中插入SQL,sql,sql-insert,create-table,circular-reference,Sql,Sql Insert,Create Table,Circular Reference,我有两张桌子: Empleados(**numEmpl**, nombre, apellido, sexo, telefono, salario, numDept) Departamentos(**numDept**, nombreDept, numDirect) 在部门: numEmpl是主键 numDept是对departmentos(numDept)的外键引用。 在部门: numDept是主键 numDirect是Empleados(numEmpl)的外键引用 所以有一个循环引用 首先,
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,然后更新它,很抱歉,我以前没有说过。
所以我必须做的唯一方法是允许循环引用,但是当我尝试用这里有人说的方式做时,它告诉我一些关于回滚的信息,有人可以帮助我?将numDirect列从departmentos表中取出。该表应简单描述该部门。根据您的业务规则,您希望部门和员工之间存在一对多的关系,或者他们之间存在多对多的关系。如果一个Empleado可以为多个departamento工作,那么您需要从Empleados表中删除numDept列,并创建另一个表来设置多对多关系
如果您想办法用当前的设计添加记录,您将遇到更大的问题。不是每个部门只有一条记录,而是每个员工都需要一条记录。要允许循环引用,您需要可延迟的约束:
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
;
在事务结束时检查可延迟约束;在提交时间之前,允许存在虚假的无效数据库状态(在原始问题中:在两个insert语句之间)。但是语句必须在事务内部,因此语句应该包含在
BEGIN[WORK]中代码>和提交[工作]代码> 循环引用是危险的,它会导致您需要返回并更新数据,以避免数据处于不一致的状态
如果你仍处于计划阶段,我敦促你考虑其他选择来避免这种情况,否则你可能会遇到很多麻烦
如果您仍然希望使用它们,那么我建议在departments表中将NULL设置为允许的值(这允许您插入一个没有d的新值),插入employee,然后返回并使用员工id进行更新。发生这种情况的原因是,只有在员工表中为该员工创建了记录(numEmpl=1)后,才能在部门表中为numDirect创建值为1的记录。在创建员工的部门记录之前,您无法创建该员工。解决这个问题的方法是将过程分为三个步骤,而不是两个步骤。为此,您必须能够创建不带numDirect FK值的部门记录,或者创建不带numDept FK值的员工
假设你决定后者。在这种情况下,在表EMPLEADOS
中使NumDept
为空:
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
Sql Server在几个版本之前删除了延迟选项,只有Oracle有,Postgres也有。(出于某种原因,我想)我不知道他们是否在ANSI,我想他们在。顺便说一句:问题是/被标记为SQL,而不是SQL-server。是的,这很好,这个问题让我充满了希望,如果有评论说SQL server不起作用,我会节省一些时间。在这种情况下(IMHO)OP,你不应该将SQL与microsoft SQL混淆。结束