我的架构有3列:ID1
,ID2
,Status
上面的每一列都是一个字符串。
我想创建一个约束,如下所示:
不能有多个具有相同ID1
和ID2
且处于“未处理”状态的记录。如果有多个记录具有相同的ID1
和ID2
且未处于UNPROCESSED状态,则可以。
是否可以在SQL Server中执行此操作?
答案 0 :(得分:2)
假设您使用的是SQL Server 2008或更高版本,则可以应用filtered index:
CREATE UNIQUE INDEX UQ_Unprocessed_IDs ON UnnamedTable (ID1,ID2)
WHERE (Status='Unprocessed')
答案 1 :(得分:1)
我不相信你能用限制来做到这一点。您需要在插入/更新操作上实现触发器。 SQL Server的问题是触发器是'AFTER'触发器。没有“BEFORE”触发器(尽管有一个'INSTEAD OF'触发器类型。
因此,您需要执行所有工作来执行事务,审核它并在约束失败时将其回滚,而不是简单地检查事务是否会导致违反约束。
答案 2 :(得分:0)
我会做一些名为ProcessedId(而不是Status)的列,并根据正在处理的ID1和ID2分配值。澄清一下,见下文
[ID1,ID2,ProcessId]
SomeId1,SomeId2,-1
SomeOtherId1,SomeOtherId2,100304
因此,任何未经处理的Ids集合将始终具有-1的ProcessId,阻塞和重复,并且任何PROCESSED的Id集合将被分配某种序列号,从而允许重复。有意义吗?
继续上面的例子,如果记录集再次进入未经处理状态,则其ProcessId为-1并导致PK违规。
答案 3 :(得分:0)
您可以使用两个基础表联合的视图执行此操作,一个用于已处理的记录,另一个用于未处理的报告。
但是,视图本身不能更新,如果记录从处理后更改为未处理,并且经常这样做,这将表现不佳。
它还会使您对并行处理场景的思考变得更加复杂。
上述两个限制都是因为您要通过delete + insert替换某些更新。
如果您至少拥有SQL Server 2008,则过滤索引通常是更好的解决方案。