2011-02-10 81 views
0

使用SQL Server 2008SQL Server - 自我引用约束

我有一个包含股票/股票/安全信息的表。这个表格包含可能拥有的股票。

每只股票都有与之相关的货币。问题在于货币也是一种股票,也是可以拥有的。即当现金举行

create table Stock 
(
StockId int identity(1,1) not null CONSTRAINT StockPK PRIMARY KEY, 
stockName varchar(100), 
... 
CurrencyId CONSTRAINT StockCurrencyIDFK FOREIGN KEY REFERENCES Stock(StockID), 
) 

对于现金行CurrencyId将等于StockId

我的问题就是如何让货币数据到表中。在插入时如何使用stockID的标识值填充CurrencyID列?

+0

是否通过存储过程或触发器完成对此表的所有插入操作?如果我们摆脱了IDENTITY()属性并自己实现IDENTITY(),我们可以拉出一些技巧,但是您确实希望确保该代码只存在于一个地方。 – 2011-02-10 13:23:30

+0

是否有一个原因,您不能在单独的表中使用货币? – JNK 2011-02-10 13:24:35

回答

0

首先,我认为在CurrencyId(可能是int)之后必须有一个类型说明符。

继续你的问题,如果你坚持这样的设计,我认为插入自引用行可以在触发器的帮助下完成。只有CurrencyId应该允许NULL,即不要将其定义为NOT NULL(你不在你的例子中,有多幸运)。这里有一个问题:NULL应该允许在技术上,但不是逻辑,那就是你必须始终有一个值,否则触发器会为你填充。

顺便说一句,当我们谈论的触发器,这里有一个可能的实现:

CREATE TRIGGER Stock_UpdateCurrencyId 
ON Stock 
FOR INSERT, UPDATE 
AS 
UPDATE Stock 
SET CurrencyId = StockId 
FROM inserted 
WHERE Stock.StockId = inserted.StockId 
    AND inserted.CurrencyId IS NULL 

所以,这个想法基本上是这样的:如果你插入一行空CurrencyId(或更新CurrencyId与NULL),这意味着你想要行参考自己(至少这是触发器会认为你想要的),否则你指定正确的参考值CurrencyId和触发器绕过这样的行。

还记得我说你不应该在逻辑设计中允许NULL吗?好吧,我这样说可能太仓促了。实际上,如果只为INSERT定义触发器,则可以存储NULL,但只能在插入之后,通过后续的UPDATE。但我宁愿没有NULL。

无论如何,你还喜欢你的设计吗?