我可以使用嵌入式业务逻辑创建高级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]);