2017-07-26 36 views
0

請閱讀我的免責聲明下來之前投票約束,3個FKS有一個空,SQL Server 2012中,DB理論只有

我有如下表。

Inventory (InventoryID (PK), LocationID (FK), ProductID (FK), BookID (FK), Quantity) 

我當前的約束強制執行,要麼在BookIDProductID不能爲給定的行空,並且LocationID不能爲空。

我想要一個強制執行以下操作的約束:LocationID + ProductID + BookID必須是唯一的。換句話說,我不希望書籍或產品在同一地點出現兩次。

要清楚,對於任何記錄,ProductIDBookID可以爲空,但不能同時爲空,且LocationID不能爲空。

免責聲明:

  1. 這個問題是完全基於個人的好奇心。結果不會以任何方式影響分級分配。我只是好奇

  2. 任何回答這應該足夠的經驗來承擔排除細節

  3. 我只是在尋找一個可能的約束,或類似的解決方案。我不在尋找返工

+1

的SQL Server 2013 ??? –

+0

@GordonLinoff這就是所有酷酷的孩子們使用的。 – Xedni

+0

對不起,2012.錯字。 – gravityclown

回答

1

在SQL Server中,唯一約束/索引只允許一個NULL值。所以,我認爲你可以做你想要用過濾指數是什麼:

create unique index unq_inventory_LocationID_ProductID_BookID 
    on inventory(LocationID, ProductID, BookID) 
    where LocationID is not null and ProductID is not null and BookID is not null; 

check約束應採取的其他條件的照顧。

編輯:

啊,我明白了。您需要兩個唯一約束:

create unique index unq_inventory_LocationID_ProductID 
    on inventory(LocationID, ProductID) 
    where LocationID is not null and ProductID is not null; 

create unique index unq_inventory_LocationID_BookID 
    on inventory(LocationID, BookID) 
    where LocationID is not null and BookID is not null; 

或者,如果你喜歡一個唯一索引,你可以使用一個計算列:

alter table inventory add BookId_or_ProductId as (coalesce(BookId, ProductId)); 

create unique index unq_inventory_LocationID_BookID_ProductId 
    on inventory(LocationID, BookId_or_ProductId); 
+0

感謝您花時間提供建設性的答案。請在我的後續問題中原諒我的天真。沒有記錄,所有3個字段都滿足不爲零的條件。 LocationID永遠不會爲空,但是在任何給定記錄中,ProductID或BookID都將爲null。 ProductID和BookID不爲null的記錄不存在。這個指數是否仍然有效? – gravityclown

+0

這完美的作品。非常感謝! – gravityclown

+0

非常感謝您的其他選擇。我帶着這兩個獨特的索引,但我會把這個合併的想法保留在我的口袋裏。再次感謝。 – gravityclown