2016-11-23 100 views
4

我有一個表,如:創建複合鍵

Id PersonId  Phone IsPrimary 
----------------------------------- 
1  1   12345  1 
2  1   55555  0 
3  2   66666  1 
4  3   77777  1 
5  3   88888  0 
6  3   99999  0 

我怎樣才能創建約束,使插入此表中只有一個值isPrimary = 1元PERSONID。對於所有PERSONID應該只有一個值isPrimary = 1那麼,結果我就無法插入下一條記錄:

Id PersonId  Phone IsPrimary 
    ----------------------------------- 
    1  1   00000  1 
+1

一種方法是僅允許通過[存儲過程]更新此表(https://msdn.microsoft.com/en-us/library/ms190782.aspx?f=255&MSPPError=-2147217396)。您可以使用SP來執行您的業務邏輯。 –

+0

在插入過程中創建一個替代觸發器將允許您在插入值之前檢查此條件 – krish

回答

9

你可以嘗試創建一個獨特的過濾指數:

CREATE UNIQUE INDEX UQ_Person_isPrimary 
ON Person (PersonId, IsPrimary) 
WHERE IsPrimary = 1 
+0

不知道SQL Server有這個,我只認爲Oracle有它。你知道這是第一個版本嗎? –

+0

@RaduGheorghiu這是SQL Server 2008. –

+0

也不知道它,+1。 – sagi

4

你試圖創建一個使用數據,而不是實際的關係,兩個實體之間的關係。每個人都有一個主要電話號碼和多個非主要電話號碼。相反,描述使用數據(在你的情況下,IsPrimary列)主電話號碼的關係,應該改爲在人員表的外鍵:

Persons table 
============= 

PersonId Name  PrimaryPhoneId 
----------------------------------- 
1   Alice  1 
2   Bob  3 
3   Charlie 4 



Phones table 
============ 

Id PersonId Phone 
--------------------- 
1 1   12345 
2 1   55555 
3 2   66666 
4 3   77777 
5 3   88888 
6 3   99999 

這樣一來,一個人只能有一個主電話。另外,如果有人切換主電話號碼,則只需更新一行。如果您持有IsPrimary列,則必須更新兩行(將舊主設置爲0,然後將新主設置爲1),並確保兩次更新都發生在同一事務中,否則可能會丟失主要如果第二行無法更新。