2014-02-25 136 views
0

是否有可能具有複雜的檢查約束?SQL擴展檢查約束

例如我有一個客戶表,其中每個記錄都分配了一個客戶類型。

因此,我可以有幾個相同類型的客戶。

我想爲每種類型設置一個客戶作爲該類型的「主要」帳戶,但每種類型只有一個客戶可以是主要客戶。

是否可以在IsPrimary字段上添加檢查約束條件,檢查所有相同類型的客戶是否已經有一個標記爲主要的客戶?

我可以在C#代碼中做到這一點,但我希望這是一個額外的檢查。

我也可以使用觸發器,但我想堅持約束,以便我可以以同樣的方式處理所有錯誤的錯誤。

謝謝

+0

'CHECK'約束只能約束單列(列檢查約束)或單列中的所有列(表檢查約束)。標準SQL也描述了'ASSERTION',它可以應用於表中的所有行,但我並不認爲已經有很多研究探討如何使ASSERTION有效地執行,因此大多數數據庫系統實際上並不實際執行它們。 –

回答

4

這不完全是一個檢查約束問題。這是一個過濾的唯一索引問題。

create unique index customers_type_isprimary on customers(type) 
    where isPrimary = 1; 

這將保證最多隻有一個客戶有每種類型的isPrimary標誌設置。

編輯:

篩選索引是一個有趣的創作。除了documentation之外,還有各種資源解釋它們(如this)。

這個想法是隻在與索引創建步驟中的where子句相匹配的行上構建索引。這樣做的一個原因是減小索引的大小。

以下是您的數據結構用例。您可能有一堆查詢在isPrimary = 1上進行過濾。你永遠不會在isPrimary = 0上過濾 - 你只需從where條款中刪除。爲什麼用所有不必要的值來混淆索引?如果謂詞在查詢中,則可以使用索引。

unique指數的情況更具說服力。已篩選的唯一索引完全符合您的要求 - 確保爲每種類型設置至多一個值爲IsPrimary。它通過在type上創建索引來執行此操作,僅適用於設置了IsPrimary的客戶。索引中的「獨特」部分保證每種類型只在索引中出現一次,並且只有一個客戶可以爲type設置IsPrimary

+0

請原諒我是一個白癡,但你能否進一步解釋一下這是如何工作的?從我對索引的理解來看,這沒有任何意義。 –

+0

謝謝你的工作就像一個夢想 –