2014-01-17 58 views
1

我有表包含ISDEFAULT柱:指數強制執行位列每桌一個TRUE值

CREATE TABLE CustomerType 
(
    ID int IDENTITY(1,1) NOT NULL, 
    Name nvarchar(50) NOT NULL, 
    IsDefault bit NOT NULL 
) 

的ISDEFAULT值應,自然是TRUE對於只有一行,所有其他行應該是FALSE。我想在數據庫級別強制執行此規則。

目前,我通過它加入了新的計算列,並放置一個唯一的非聚集索引實現這一目標:

CREATE TABLE CustomerType 
(
    ID int IDENTITY(1,1) NOT NULL, 
    Name nvarchar(50) NULL, 
    IsDefault bit NOT NULL 
    IsDefaultConstraint AS (CASE WHEN IsDefault = 1 THEN 1 ELSE -ID END), 
) 

CREATE UNIQUE NONCLUSTERED INDEX UQ_CustomerType_IsDefault ON CustomerType 
(
    IsDefaultConstraint ASC 
) 

這只是正常的,但有一點代碼味道的吧,因爲額外的列沒有按」 t包含相關數據,僅用於實施唯一索引。

是否有其他方法來強制執行相同的行爲?

回答

3

對於SQL Server 2008或更高版本,使用filtered index

CREATE UNIQUE INDEX IX_Default on CustomerType (IsDefault) WHERE IsDefault = 1 

對於舊版本,你可以使用「窮人的過濾索引「,indexed view

CREATE VIEW dbo.DRI_CustomerType_Default 
WITH SCHEMABINDING 
AS 
    SELECT IsDefault FROM dbo.CustomerType WHERE IsDefault = 1 
GO 
CREATE UNIQUE CLUSTERED INDEX IX_Default on DRI_CustomerType_Default (IsDefault) 
0

不幸的是,SQL-Server不提供基於函數的索引,這就是你正在尋找的。所以你的方法是最好的。

如果額外的列太煩人,那麼在隱藏該列的表上使用一個視圖。

如果這仍是惹你生氣了,請切換到Oracle ;-)

+1

你有沒有試過在Oracle論壇上找到答案?我寧願使用基於紙張的數據庫,而不願意靠近Oracle,因爲從https://communities.oracle.com/ –

+0

Oracle論壇獲得任何幫助簡直太糟糕了。我總是使用stackoverflow.com :-) –

+1

SQL Server只有5年的篩選索引。對於這個問題,可以使用索引視圖來模擬篩選索引,這些視圖至少在2000年版本的產品中已經出現。 –