如何拥有引用另一个表的检查约束?
我在 SQL Server 2008 数据库中有以下表:
tblItem,其中有一个 ItemID 字段;
tblGoodItem,它也有一个 ItemID 字段,并且有一个指向 tblItem 的外键;
tblBadItem,它也有一个 ItemID 字段,并且还有一个指向 tblItem 的外键。
一个物品不可能既是好物品又是坏物品;它必须是其中之一或另一个。然而,无论物品是好还是坏,它都必须是物品。
我的问题是:如何向 tblGoodItem 和 tblBadItem 中的 ItemID 字段添加约束,以便 ItemID 值不能同时存在于两个表中?
我在 Stack Overflow 上读过一些关于类似问题的回复,我正在考虑这个解决方案:
创建一个视图 vwItem,它将 tblGoodItem 加入到 ItemID 上的 tblBadItem 上。
编写一个 UDF fnItem,它对 vwItem 进行查询,以查看视图中存在多少条记录。
有一个调用 fnItem 并验证返回值是否为 0 的约束。
这是最好的主意吗?有人有更好的主意吗?
I have the following tables in a SQL Server 2008 db:
tblItem, which has an ItemID field;
tblGoodItem, which also has an ItemID field, and has a foreign key pointing to tblItem;
tblBadItem, which also has an ItemID field, and also has a foreign key pointing to tblItem.
An item cannot be both a good item and a bad item; it must either be the one or the other. However, whether the item is good or bad, it must be an item.
My question is this: how do I add a constraint to the ItemID fields in both tblGoodItem and tblBadItem so that an ItemID value cannot exist in both tables?
I've read some replies in Stack Overflow on similar questions, and I'm thinking of this solution:
Create a view vwItem which joins tblGoodItem on tblBadItem on ItemID.
Write a UDF fnItem which does a query on vwItem to see how many records exist in the view.
Have a constraint which calls fnItem and verifies that the value returned is 0.
Is this best idea? Does anyone have a better idea?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
添加一列 tblItem.ItemType 列。这一列在任何给定行上只能有一个值(显然)。添加对 ItemID、ItemType 的唯一约束。
现在的技巧是:很少有人记得这一点,但外键可以引用唯一约束的列。
如果将每个子表中的 ItemType 限制为固定值,则 tblItem 中的给定行只能由一个子表引用。
不过,将项目从好变为坏需要三个步骤:
Add a column tblItem.ItemType column. This column can have only one value on any given row (obviously). Add a unique constraint over ItemID,ItemType.
Now the trick: few people remember this, but a foreign key can reference the columns of a unique constraint.
If you constrain ItemType in each of the child tables to a fixed value, then a given row in tblItem can be referenced by only one child table.
It's a three-step process to change an item from good to bad, though:
摆脱 tblGoodItem 和 tblBadItem 并创建一个具有 ItemType="G" 或 "B" 的新表,并在 ItemID 上放置唯一索引或键,则不需要对 tblItem 进行约束。
get rid of tblGoodItem and tblBadItem and make a new table with a ItemType="G" or "B" and put an unique index or key on ItemID, then no constraint is needed on tblItem.
我可能不理解您的业务需求,但为什么您希望为好项目和坏项目建立一个单独的表?这些不是同一事物的抽象吗?
为什么不使用 isBadItem 标志或更具体地说是 itemConditionStatus 列。
I'm probably not understanding your business requirements here but why do you wish to have a separate table for Good and Bad items? Are these not abstractions of the same thing?
Why not use an isBadItem flag or more specifically an itemConditionStatus column.
在 tblItem 中,添加 itemType 列。有一个检查约束来确保 itemType 是好还是坏。创建对 (ItemID, itemType ) 的唯一约束
将 itemType 列添加到坏项目表和好项目表中。有一个检查约束来确保 itemType 在好的表中是好的,在坏的表中是坏的。
In tblItem, add itemType column. Have a check constraint to make sure that itemType is either good or bad. Create a unique constraint on (ItemID, itemType )
Add itemType column to both bad and good items tables. Have a check constraint to make sure that itemType is good in good table, and bad in bad table.
您不能在
CHECK
约束中使用SELECT
语句 - 这并不是它们的设计目的。我认为最好的选择是在 ItemId 中编写 UDF 传递并检查它是否存在。对于这种情况,这确实是最简单的选择。
我添加了一些测试数据和示例函数。
You can't use a
SELECT
statement in aCHECK
Constraint - thats not really what they were designed for.I think your best option would be to write a UDF pass in the ItemId and check if it exists. For this scenario it really is the easiest option.
I've added some test data and an example function.