目前在我们的数据库设计中,我们在两个实体之间存在循环引用。换句话说,我们在每个表中都有外键,它们引用彼此的主键。为了在这些表中插入记录,我们需要执行延迟约束检查。这在 SQL Server 2008 中可能吗?我知道 Oracle DDL 有专门的语法。
SQL Server 中没有执行延迟约束检查的本机方法。
您的最佳选择可能是将 NULL 值插入第一个表中的外键列,直到插入第二条记录,然后作为同一事务的一部分,更新第一个表中的外键列。
我感兴趣 - 您的循环引用的商业原因是什么?这绝对是一个非凡的要求。
另请查看关于同一主题的此线程。
我假设您的循环 FK 约束是为了确保表扩展目的的一对一关系?
案例 1 - 数据插入是作为某种数据修复完成的:
在数据插入期间,您需要禁用约束(假设您在 FK 定义中使用显式命名约束,这是一个很好的做法)。
例如
-- 准备 - 禁用 FK 约束
更改表 dbo.TableMain NOCHECK 约束 FK_TableMain_TableExtension_ID
更改表 dbo.TableExtension NOCHECK 约束 FK_TableExtension_TableMain_ID 去吧
-- 在两个表中插入内容,确保数据完整性 ... ... ... 去吧
-- 重新启用您的约束
更改表 dbo.TableMain 检查约束 FK_TableMain_TableExtension_ID
更改表 dbo.TableExtension 检查约束 FK_TableExtension_TableMain_ID 去吧
案例2 - 一对一的主/从表结构
如果您以某种方式允许用户添加到一个表,而另一个表充当从表,那么显然您不希望频繁禁用/启用约束。
相反,应该考虑只从从表到主表有FK,但为了保证1对1,还要将FK定义为从表中的PK。
创建表 dbo.Master { i_masterId INT NOT NULL 主键 , ...其他列 }
创建表 dbo.Slave { i_masterId INT NOT NULL 主键 , ...其他列 , 约束 [FK_Slave_ToMaster] 外键 (i_masterId) 引用 dbo.Master(i_master), }
如果您希望始终自动创建 dbo.slave,请在主表上定义 INSERT 触发器。