2016-04-07 12 views
1

我在當前位置遇到需要分配TLC的數據庫,至少可以這麼說,有許多交叉引用表都具有相同的架構模式明智,並使用觸發器來強制執行業務邏輯或域看起來完整。我想弄清楚是否可以用約束替換一些觸發器。以下是符合此模式的典型表格定義。這些表格中大約有400個都使用相同的基於觸發器的解決方案。如何在不使用觸發器的情況下爲一對多關係設置額外約束

CREATE TABLE dbo.FooXRef 
(
FooXRefID INT NOT NULL IDENTITY(1,1) PRIMARY KEY, 
BarID INT NOT NULL CONSTRAINT [fk_Bar] FOREIGN KEY REFERENCES dbo.Bar(BarID), 
DefaultRecord BIT NOT NULL CONSTRAINT [DF_FooXRef_Default] DEFAULT(1) 
); 

的規則是可以存在的具有相同值的記錄無限數量BarIDDefaultRecord = 0,但只能存在一個記錄,其中BarID是表和DefaultRecord = 1

我需要設置哪種類型的約束以允許組合?

此表結構和觸發器強制執行此組合在當前數據庫中爲400,而在下一個數據庫中則執行此操作。是不是可以設置一個適用於這種情況的約束條件?

+0

不幸的是,基於該示例,您必須以編程方式進行維護。 –

+0

這個例子[這裏](https://technet.microsoft.com/en-us/library/ms188258%28v=sql.105%29.aspx)能給你什麼想法嗎? – HABO

回答

2

這是一個不使用觸發器的可能變體。

使用過濾條件WHERE ([DefaultRecord]=(1))(BarID, DefaultRecord)上創建過濾的唯一索引。

有了這樣的索引,您可以插入只有一行BarIDDefaultRecord = 1

有可能有零個數的行數爲DefaultRecord = 1

有可能有任何數量的行有DefaultRecord = 0

CREATE UNIQUE NONCLUSTERED INDEX [IX_DefaultRecord] ON [dbo].[FooXRef] 
(
    [BarID] ASC, 
    [DefaultRecord] ASC 
) 
WHERE ([DefaultRecord]=(1)) 
+0

是的,它有可能有0行的默認記錄= 1。是的,也可以有任意數量的行默認記錄= 0。我會嘗試應用您的建議,看看我得到的。 – SSISPissesMeOff

+0

像一個魅力工作。非常感謝你。我甚至沒有想到一個獨特的索引,而不是一個檢查約束。 – SSISPissesMeOff

+0

不客氣。我很高興你發現這個答案有用。我編輯了問題的標題,並試圖使其更具描述性。 –

相關問題