我的表包含IsDefault列:
CREATE TABLE CustomerType
(
ID int IDENTITY(1,1) NOT NULL,
Name nvarchar(50) NOT NULL,
IsDefault bit NOT NULL
)
IsDefault值当然应仅为TRUE
一行,所有其他行应为FALSE
。我想在数据库级别强制执行此规则。
目前我通过添加一个新的计算列并在其上放置一个独特的NONCLUSTERED INDEX来实现这一目标:
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
)
这很好用,但它有一些代码味道,因为额外的列不包含相关数据,仅用于强制执行唯一索引。
是否有其他方法可以强制执行相同的行为?
答案 0 :(得分: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)
答案 1 :(得分:0)
不幸的是,SQL-Server不提供基于功能的索引,这正是您要寻找的。所以你的方法是最好的。
如果附加列太烦人,则使用隐藏该列的表上的视图。
如果这仍然让你讨厌,请切换到Oracle; - )