1
Widget Version Latest
XYZ 1.0 0
XYZ 1.1 0
XYZ 1.2 1
ABC 1.0 1
有没有一种方法来创建一个约束,说
每个插件版本的组合可以有任意数量的0为 最新版本的标志,但必须有确切1发生在哪里 最新标志是1
?
还是我必须使用触发器或类似的?
Widget Version Latest
XYZ 1.0 0
XYZ 1.1 0
XYZ 1.2 1
ABC 1.0 1
有没有一种方法来创建一个约束,说
每个插件版本的组合可以有任意数量的0为 最新版本的标志,但必须有确切1发生在哪里 最新标志是1
?
还是我必须使用触发器或类似的?
我看到两种方法(第三个是使用视图,但它是相当类似于第二溶液)
首先,有检查约束
东西(这个人是丑陋,但你的想法):
create function [dbo].[checkLatest](@widget varchar(3))
returns bit
as
begin
declare @numOfLatest int;
declare @lastValue int;
declare @maxVersion decimal(18,2);
select @maxVersion = MAX([Version]) from Table1 where Widget = @widget;
--check if there's only one Latest = 1 by Widget
select @numOfLatest = COUNT(*) from Table1 where Widget = @widget and Latest = 1;
--check if Latest = 1 for max version
select @lastValue = Latest from Table1 where [Version] = @maxVersion and Widget = @widget;
return case when @numOfLatest = 1 and @lastValue = 1 then 1 else 0 end
end
GO
然后
ALTER TABLE Table1
WITH CHECK ADD CONSTRAINT CK_LAtest
CHECK (checkLatest(Widget) = 1)
注意:你必须当你把你所有的最新标志0在存储过程中停用约束,然后重新激活它。您可能需要锁定你的表以避免任何插入/更新,而约束是停用...
另一种方式将使用计算科拉姆 n表示Latest
:
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]);
,因为它的计算,这是永远不会是错的,但是... SELECT
语句将花费更多...可依您的数据更大小。
真棒答案 - 学会两个伟大的事情。谢谢。 – Ryan
问题:当您插入新行(用最新版本),你必须把最新的。例如,'小工具:XYZ','版本:1.3'。所以这一个必须有最新= 1,但是'XYZ/1.2'必须更新以使最新= 0,因为它不再是最新值。有一段时间,您需要接受两条最新= 1(通过窗口小部件)或没有最新= 1的线...... –
在我的s/p中,我先删除所有现有窗口小部件版本上的最新标志,我认为这符合上面的约束。 – Ryan
那么,当你删除标志,有一个而当'必须恰好1 occurence其中最新的标志是1'不再有效...... –