Tol*_*ayi 7 sql t-sql sql-server check-constraints sql-server-2008
我在SQL Server 2008 db中有以下表:
tblItem,它有一个ItemID字段;
tblGoodItem,它还有一个ItemID字段,并且有一个指向tblItem的外键;
tblBadItem,它也有一个ItemID字段,并且还有一个指向tblItem的外键.
物品既不是好物品,也不是坏物品; 它必须是一个或另一个.但是,无论项目是好还是坏,它都必须是一个项目.
我的问题是:如何在tblGoodItem和tblBadItem中的ItemID字段中添加约束,以便两个表中都不能存在ItemID值?
我已经在类似的问题上阅读了Stack Overflow中的一些回复,我正在考虑这个解决方案:
创建一个视图vwItem,它在ItemID上的tblBadItem上连接tblGoodItem.
编写一个UDF fnItem,它对vwItem执行查询以查看视图中存在多少条记录.
有一个约束调用fnItem并验证返回的值是0.
这是最好的主意吗?有没有人有更好的主意?
添加列tblItem.ItemType列.此列在任何给定行上只能有一个值(显然).在ItemID,ItemType上添加唯一约束.
现在的诀窍:很少有人记住这一点,但外键可以引用唯一约束的列.
CREATE TABLE tblItem (
ItemID INT PRIMARY KEY,
ItemType CHAR(1),
UNIQUE KEY (ItemID, ItemType)
);
CREATE TABLE tblGoodItem (
ItemID INT PRIMARY KEY,
ItemType CHAR(1),
CHECK (ItemType='G')
FOREIGN KEY (ItemID, ItemType) REFERENCES tblItem(ItemID, ItemType)
);
CREATE TABLE tblBadItem (
ItemID INT PRIMARY KEY
ItemType CHAR(1),
CHECK (ItemType='B')
FOREIGN KEY (ItemID, ItemType) REFERENCES tblItem(ItemID, ItemType)
);
Run Code Online (Sandbox Code Playgroud)
如果将每个子表中的ItemType约束为固定值,则tblItem中的给定行只能由一个子表引用.
这是一个将项目从好变为坏的三个步骤: