我可以使用嵌入式业务逻辑创建高级SQL约束吗?

我可以使用嵌入式业务逻辑创建高级SQL约束吗?,sql,sql-server-2008,constraints,Sql,Sql Server 2008,Constraints,如果我有桌子 Widget Version Latest XYZ 1.0 0 XYZ 1.1 0 XYZ 1.2 1 ABC 1.0 1 有没有一种方法可以创建一个约束 每个小部件版本组合可以有任意数量的0用于 最新版本标志,但必须在 最新的国旗是1 ? 或者我必须使用触发器或类似的方法吗?我看到两种方法(第三种方法是使用视图,但与第二种解决方案非常类似) 首先,带有检查约束 有些东西(这件很难看,但你有这个想法):

如果我有桌子

Widget  Version  Latest
XYZ     1.0      0
XYZ     1.1      0
XYZ     1.2      1
ABC     1.0      1
有没有一种方法可以创建一个约束

每个小部件版本组合可以有任意数量的0用于 最新版本标志,但必须在 最新的国旗是1

?

或者我必须使用触发器或类似的方法吗?

我看到两种方法(第三种方法是使用视图,但与第二种解决方案非常类似)

首先,带有检查约束

有些东西(这件很难看,但你有这个想法):

然后

注意:当您在存储过程中将所有最新的标志都设置为0时,必须停用约束,然后重新激活它。在禁用约束时,您可能需要锁定表以避免任何插入/更新


另一种方法是对
最新的
使用计算列n:

create function setLatest(@Widget varchar(3), @Version decimal(18,2))
returns bit
as 
begin
declare @result bit = 0;

with cte as (select  [Version], ROW_NUMBER() over(PARTITION by [Widget] order by [Version] desc) rn from dbo.Table1 where Widget = @Widget)
select @result = case when @Version = [Version] then 1 else 0 end from 
cte where rn = 1
and @Version = [Version]
return @result;
end
然后放下你的最新专栏

alter table Table1 drop column Latest;
并将其作为计算列重新添加

alter table Table1 add Latest as setLatest(Widget, [Version]);

经过计算,它永远不会错,但是<代码>选择
语句将花费更多。。。可能取决于数据的大小。

问题:当插入新行(具有最新版本)时,必须将最新的设置为1。例如,
小部件:XYZ
版本:1.3
。所以这一个必须有Latest=1。但是必须更新
XYZ/1.2
,使Latest=0,因为它不再是最新的值。有时,您需要接受两行Latest=1(通过widget),或者不接受任何一行Latest=1…在我的s/p中,我将首先删除所有现有widget版本上的最新标志,我认为这符合上面的约束条件。嗯,当您删除标志时,有一段时间,
必须正好出现一次,其中最新标志为1
不再有效…您可以创建一个唯一的筛选索引,以确保在最新标志为
1
的情况下最多出现一次,但正如拉斐尔所说,如果不变量正好是一,那么维护一个表是非常困难的。很好!非常感谢。我想约束应该是“最多一个组合,其中latest=1”
alter table Table1 drop column Latest;
alter table Table1 add Latest as setLatest(Widget, [Version]);