在具有循环引用的表中插入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)
在部门:

  • numEmpl是主键
  • numDept是对departmentos(numDept)的外键引用。 在部门:
  • numDept是主键
  • numDirect是Empleados(numEmpl)的外键引用
  • 所以有一个循环引用

    首先,我创建了表:

    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混淆。结束