在SQL中输入数据时处理循环引用

Tom*_*Tom 8 sql

您使用什么样的SQL技巧将数据输入到两个表中,其中包含循环引用.

Employees
    EmployeeID <PK>
    DepartmentID <FK> NOT NULL

Departments
    DepartmentID <PK>
    EmployeeID <FK> NOT NULL
Run Code Online (Sandbox Code Playgroud)

员工属于某个部门,部门必须有经理(部门主管).

我是否必须禁用插入的约束?

cha*_*aos 13

我假设你的Departments.EmployeeID是一个部门负责人.我要做的是让那个列可以为空; 然后你可以先创建部门,然后创建员工.

  • +1 - 使列可为空可行是一种可行的方法. (3认同)

spe*_*593 5

问:我是否必须禁用插入的约束?
答:在Oracle中,不,不是外键约束DEFERRABLE (参见下面的示例)

对于Oracle:

    SET CONSTRAINTS ALL DEFERRED;
    INSERT INTO Departments values ('foo','dummy');
    INSERT INTO Employees values ('bar','foo');
    UPDATE Departments SET EmployeeID = 'bar' WHERE DepartmentID = 'foo';
    COMMIT;

让我们解压一下:

  • (自动提交必须关闭)
  • 推迟执行外键约束
  • 在Department表中插入一行,其中FK列的"哑"值
  • 使用FK引用部门向Employee表插入一行
  • 用实际参考替换Department FK中的"dummy"值
  • 重新启用约束的执行

注意:禁用外键约束对所有会话生效,DEFERRING约束处于事务级别(如示例中所示)或会话级别(ALTER SESSION SET CONSTRAINTS=DEFERRED;)

Oracle允许将外键约束定义为DEFERRABLE至少十年.我定义所有外键约束(当然)是可以直接推断的.这保持了所有人期望的默认行为,但允许操作而不需要禁用外键.

请参阅AskTom:http://www.oracle.com/technology/oramag/oracle/03-nov/o63asktom.html

请看AskTom:http://asktom.oracle.com/pls/asktom/f p = 100:11:0 ::::P11_QUESTION_ID:10954765239682

另见:http://www.idevelopment.info/data/Oracle/DBA_tips/Database_Administration/DBA_12.shtml

[编辑]

答:在Microsoft SQL Server中,您无法像在Oracle中那样推迟外键约束.禁用和重新启用外键约束是一种方法,但我对1)性能影响(在重新启用约束时检查ENTIRE表的外键约束)的前景感到不寒而栗,2)处理异常如果(何时?)重新启用约束失败.请注意,禁用约束将影响所有会话,因此在禁用约束时,其他会话可能会插入和更新将导致约束重新启用失败的行.

对于SQL Server,更好的方法是删除NOT NULL约束,并在插入/更新行时允许NULL作为临时占位符.

对于SQL Server:

    -- (with NOT NULL constraint removed from Departments.EmployeeID)
    insert into Departments values ('foo',NULL)
    go
    insert into Employees values ('bar','foo')
    go
    update Departments set EmployeeID = 'bar' where DepartmentID = 'foo'
    go

[/编辑]