如何为表添加检查约束限制两个FK的非空互斥规则
实现FooBar表的互斥外键检查约束
你写的这条ALTER TABLE语句完全没问题,里面的OR是正常生效的:
alter table [FooBar] add constraint chk_foobar_excluding_rule check ((FooId IS NULL and BarId IS NOT NULL) or (FooId IS NOT NULL and BarId IS NULL));
约束逻辑说明
这个约束的逻辑正好匹配你的需求:
- 第一个分支
(FooId IS NULL and BarId IS NOT NULL):限制FooId为空时,BarId必须有值 - 第二个分支
(FooId IS NOT NULL and BarId IS NULL):限制FooId有值时,BarId必须为空 - 用OR连接两个分支,意味着只有满足其中一种情况的记录才能被插入/更新,自动排除了以下两种非法场景:
- FooId和BarId同时有值
- FooId和BarId同时为NULL
测试验证
用你给出的插入语句测试,结果完全符合预期:
-- 非法:两个外键都有值,触发约束报错 INSERT INTO FooBar (FooId, BarId) VALUES (12, 22); -- 报错:check constraint violated -- 非法:两个外键都为空,触发约束报错 INSERT INTO FooBar (FooId, BarId) VALUES (NULL, NULL); -- 报错:check constraint violated -- 合法:仅FooId有值,插入成功 INSERT INTO FooBar (FooId, BarId) VALUES (12, NULL); -- 插入成功 -- 合法:仅BarId有值,插入成功 INSERT INTO FooBar (FooId, BarId) VALUES (NULL, 22); -- 插入成功
内容的提问来源于stack exchange,提问作者lonelydev101
相关产品推荐
相关产品推荐

