我有一张带有一些列的表..说A,B& C和最后一列名为DeletedDate。它是一个可以为空的日期时间。
我在A,B&添加了一个独特的约束。 C.它工作正常,直到我发现了一个问题。添加删除日期后。我应该可以为同一个A,B和B添加新记录。 C值。但我不能因为独特的限制。
我在这里看到两个选项
Where DeletedDate is not NULL
我的问题:哪个选项更好&为什么呢?
答案 0 :(得分:2)
选项2:唯一约束不能包含WHERE
子句。但您可以改为使用 filtered index :
CREATE UNIQUE INDEX a_b_c_UQ_when_DeletedDate_is_null
ON TableName
(a, b, c)
WHERE DeletedDate IS NULL ;
选项1:如果您只是在唯一约束中包含DeletedDate
,那么有两个问题:
一个小小的,如果SQL-Server实现了sql-Standard中的唯一约束,那将允许2行或更多行具有相同的a,b,c组合和null删除日期,所以两个或多个未删除的行可以共存,这与要求不符。当然,这不是当前实施的问题。如果SQL-Server将来决定更改实现,那么它可能只会成为一个,以符合标准。
一个更重要的问题是,这样您就不允许有2行或更多行具有相同的a,b,c组合和相同的完全删除日期。在您的情况下,这不是一个严重的问题,因为DeletedDate
是datetime
而不是date
。如果您尝试使用相同的语句/事务删除多个行,则可能只会带来一些困难。
答案 1 :(得分:1)
您可以将计算列用于唯一索引。如果1
可用,则返回静态值,如DeletedDate
,否则返回主键的负对应值。
CREATE TABLE [dbo].[Test](
[ID] [int] IDENTITY(1,1) NOT NULL,
[A] [int] NOT NULL,
[B] [int] NOT NULL,
[C] [int] NOT NULL,
[DeletedDate] [datetime] NULL,
[IsDeleted] AS (case when [DeletedDate] IS NULL then (1) else -(1)*[ID] end),
CONSTRAINT [PK_Test] PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
现在,您可以在A,B,C和IsDeleted上创建唯一索引。
答案 2 :(得分:0)
日期往往不是包含唯一索引/约束的好选择,因为它们具有有限的分辨率,并且您不会始终保证唯一值 - 如果您需要添加批量删除在路上一次性删除十件事情的功能?他们都会有相同的删除日期。
不幸的是,由于问题是(适当地)抽象地关注空问题,我不知道约束的用例是什么,所以我不能推荐另一种方法。但是,我会说" no"作为实际问题的答案,因为空问题只是具有唯一日期值的许多问题中的第一个。