多年来,我设计了大多数表格都有一个DeactivatedDate字段。我喜欢这种方法,因为它允许我查看记录何时被停用,当我有一个通过触发器记录其历史记录的表(用作审核停用日期)时,它可以实现双重目的。
我现在面临的问题是 - 是否可以添加一个仅在记录处于活动状态时强制执行某种唯一性的约束?我想这可以在一个触发器中完成,但我真的试图避免它们。如果DeactivatedDate is null or DeactivatedDate > getdate()
,该记录被视为有效。
is null检查很简单 - 这个SQL运行良好:
ALTER TABLE dbo.PersonHun ADD
IsActive AS CASE WHEN DeactivatedDate IS NULL THEN 1 ELSE 0 END
GO
CREATE UNIQUE NONCLUSTERED INDEX uix_PersonHun_RecordNum
ON PersonHun(RecordNum, OwnedByDataProvider, IsActive)
WHERE RecordNum IS NOT NULL
GO
但是,只要我将getdate()的条件添加到计算字段,我就会收到以下错误:
Msg 2729,Level 16,State 1,Line 7 Column' IsActive'在表中 ' PersonHun'不能用于索引或统计信息或分区 因为它是非确定性的。
生成错误的代码是:
ALTER TABLE dbo.PersonHun ADD
IsActive AS CASE WHEN DeactivatedDate IS NULL
OR DeactivatedDate > GETDATE() -- This line here is the culprit
THEN 1 ELSE 0 END
GO
-- Error occurs when creating the INDEX:
CREATE UNIQUE NONCLUSTERED INDEX uix_PersonHun_RecordNum
ON PersonHun(RecordNum, OwnedByDataProvider, IsActive)
WHERE RecordNum IS NOT NULL
GO
所以我想我的问题是:基于getdate()
,有没有比使用触发器强制执行某种滚动唯一约束更好的方法?
更新:谢谢大家的意见,但我认为它有点偏离主题。
我可能没有强调将来对日期字段的唯一约束的重要性。 " IsActive"我的例子中的计算字段不是我需要的东西(甚至是想要的东西) - 它只是一次尝试制作一个唯一约束条件,仅在未来的日期。
我不想以任何方式更改此表的架构,这会影响外部进程。 DeactivatedDate字段已在此表中很好地建立多年,我不想改变它。我以为我需要求助于触发器。