创建一个由多列组成的外键,但仅引用一个目标
我有两张表,我正在尝试在它们之间创建一个外键约束。表的结构大致如下:
表1:
| 名称 | 描述 | idx |
|---|---|---|
表2:
| Tbl1_idx1 | Tbl1_idx2 | idx |
|---|---|---|
两张表都以 idx 列作为主键,并且在表2 的另外两列的组合上有唯一约束。这两列都应限于表1 中 idx 列的取值,因此形成外键。然而,当我尝试执行以下查询时:
ALTER TABLE [Table2]
ADD CONSTRAINT [FK_Table2]
FOREIGN KEY ([Tbl1_idx1], [Tbl1_idx2]) REFERENCES [Table1]([idx])
ON DELETE CASCADE
它返回引用列的数量与被引用列的数量不同。不过,如果我在查询中再次引用被引用的 idx 列,它会提示指定了重复的列。
如何创建一个外键,要求两列都引用同一列?我也尝试创建两个外键,但这又返回另一个错误,称这可能会导致多条级联路径。这两列在从Table 1删除时都需要进行级联删除。
解决方案
你把示例抽象得太离谱,以至于很难理解你的意图。除了它们都引用同一个 Table1 的主键之外,两个外键列 Tbl1_idx1 和 Tbl1_idx1 之间还有没有其他特殊关系?
一个表对同一个主键有多条独立的外键引用并不少见。例如一个 ServiceRequest 表可能有一个 RequestedByPersonId 和一个 AssignedToPersonId,它们都引用同一个 Person 表的主键。在这种情况下,你只需为每个外键列定义两个独立的外键约束——为每个FK列各自对应一个。
“可能导致多条级联路径”的错误很可能是因为两个外键上都设置了 ON DELETE CASCADE(或 ON UPDATE CASCADE)选项。你可以删除其中一个或两个来消除此错误,但也应重新考虑是否真的需要在这两个表之间支持级联删除。存在多条外键很可能意味着这不是一个简单的父/子表关系,或许 Table1 行数据永远不应被删除。可以考虑改为软删除(一个 IsActive 或 IsDeleted 列)来替代。
就 ServiceRequest 的示例而言,如果员工离开公司,你真的想删除所有相关的已请求或已执行工作的历史记录吗?
另一种选择是在应用程序中处理级联,通过存储过程中的代码,或通过一个 INSTEAD OF DELETE 触发器来显式执行所需的子行删除。
另请参阅:Foreign key constraint may cause cycles or multiple cascade paths?.