对具有特定值的多个列进行约束

时间:2012-10-25 21:38:25

标签: sql sql-server database constraints

我的架构有3列:ID1ID2Status

上面的每一列都是一个字符串。

我想创建一个约束,如下所示:

不能有多个具有相同ID1ID2且处于“未处理”状态的记录。如果有多个记录具有相同的ID1ID2且未处于UNPROCESSED状态,则可以。

是否可以在SQL Server中执行此操作?

4 个答案:

答案 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,则过滤索引通常是更好的解决方案。