2011-02-10 42 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。

無論如何,你還喜歡你的設計嗎?