如何解决SQL 只允许其他列匹配的外键
我有两张桌子,
CREATE TABLE ActivityCodes (
ActivityCodeID INT NOT NULL PRIMARY KEY,LocationID INT NOT NULL
);
和
CREATE TABLE LocationSettings (
LocationID INT NOT NULL PRIMARY KEY,DefaultFooActivityCodeID INT,FOREIGN KEY (DefaultFooActivityCodeID) REFERENCES ActivityCodes(ActivityCodeID)
);
与所示的外键关系。活动代码仅对给定的 LocationID
有效,DefaultFooActivityCodeID
表中的 LocationSettings
应为 ActivityCodeID
,其中 ActivityCodes.LocationID == LocationSettings.LocationID
。如何在 sql 中强制执行?可以用约束或外键来完成吗?有可能吗?
编辑:只是添加一些说明,这些表中的有效数据应该是这样的:
ActivityCodes
ActivityCodeID | 位置 ID |
---|---|
1 | 123 |
2 | 123 |
3 | 456 |
4 | 456 |
LocationSettings
位置 ID | DefaultFooActivityCodeID |
---|---|
123 | 1 |
456 | 4 |
一个地点可以有多个活动代码。位置的默认活动代码必须是该位置的活动代码。 @Charlieface 我尝试使用 answer you linked 中建议的复合外键,但是我收到一个错误,说 LocationID
上的 ActivityCodes
既不是唯一键也不是主键(我使用的是 MS sql Server ).
解决方法
您提供的 DDL 并不代表您所描述的内容。
DDL 描述了这一点:
ActivityCodes
独立于 LocationSettings
。
LocationSettings
而是依赖于 ActivityCodes
(一个 ActivityCodes 有多个 LocationSettings
)
外键的定义很好,比如 FOREIGN KEY (DefaultFooActivityCodeID) REFERENCES ActivityCodes(ActivityCodeID)
。如果您在没有先插入 ActivityCode 的情况下尝试插入 LocationSettings,则会因违反约束而失败。
外键引用不必是主键。这允许您对同一个表有两个外键引用,即使它们是多余的:
CREATE TABLE ActivityCodes (
ActivityCodeID INT NOT NULL PRIMARY KEY,LocationID INT NOT NULL,UNIQUE (LocationID,ActivityCodeID)
);
CREATE TABLE LocationSettings (
LocationID INT NOT NULL PRIMARY KEY,DefaultFooActivityCodeID INT,FOREIGN KEY (DefaultFooActivityCodeID) REFERENCES ActivityCodes(ActivityCodeID),FOREIGN KEY (LocationID,DefaultFooActivityCodeID) REFERENCES ActivityCodes(LocationID,ActivityCodeID)
);
虽然这表达了你想要的,但你会发现这在实践中维护起来有点棘手。设置默认值需要以下步骤:
- 插入具有
NULL
默认值的位置。 - 使用默认活动在
ActivityCodes
中插入一行。 - 更新
LocationSettings
中的默认值。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。