一尘不染

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

sql

您使用哪种SQL技巧将数据输入到两个表之间,并在两个表之间使用循环引用。

Employees
    EmployeeID <PK>
    DepartmentID <FK> NOT NULL

Departments
    DepartmentID <PK>
    EmployeeID <FK> NOT NULL

员工属于部门,部门必须有经理(部门负责人)。

我是否必须禁用约束才能进行插入?


阅读 185

收藏
2021-03-10

共1个答案

一尘不染

问: 是否必须禁用约束才能进行插入?
答: 在Oracle中,否,如果外键约束为否,则为否DEFERRABLE (请参见下面的示例)

对于Oracle:

    SET约束所有延迟;
    插入部门的值('foo','dummy');
    INSERT INTO员工值('bar','foo');
    UPDATE Departments SET EmployeeID ='bar'WHERE DepartmentID ='foo';
    犯罪;

让我们解压一下:

  • (必须禁用自动提交)
  • 推迟执行外键约束
  • 在“部门”表中插入一行,并为FK列添加一个“虚拟”值
  • 在FY引用Department的行中插入Employee表
  • 用实际参考替换部门FK中的“虚拟”值
  • 重新启用约束条件

注意:禁用外键约束对所有会话都有效,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:

    -(已从Departments.EmployeeID移除NOT NULL约束)
    插入部门值('foo',NULL)
    去
    插入员工值(“ bar”,“ foo”)
    去
    更新Departments设置EmployeeID ='bar',其中DepartmentID ='foo'
    去

[/编辑]

2021-03-10