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