T-SQL唯一约束WHERE AnotherColumn = ParticularValue

时间:2010-11-04 14:10:06

标签: sql sql-server sql-server-2005 tsql

考虑一个包含以下列的链接表:

PersonID int NOT NULL
LocationID int NOT NULL
Active bit NOT NULL
...

系统允许独立配置每个人员和位置。配置完成后,每个人最多可以链接到一个位置。如果Person移动到新位置,则链接将被停用,而不是删除,以便系统知道Person最后一次链接到特定位置的时间。一个人可以有任意数量的非活动链接,但最多只能有一个活动链接。位置可以有任意数量的人员与其积极链接。

如何在此表中添加约束以防止在已存在的情况下为Person创建第二个活动链接?

编辑:我认为这是一个2008年的盒子......原来它是2005年,所以过滤后的索引不起作用。

4 个答案:

答案 0 :(得分:3)

SilverSkin建议,不是链接表,而是在Person表上有一个指向位置ID的链接。现在,如果您需要非活动列表,请在每次更改位置时向Person表添加一个触发器以插入历史记录表(链接表的修改)(<>最后一个历史表条目/一个不存在的人)。 Person表中的链接给出了活动链接,而历史表给出了历史记录和(如果一个人在位置之间打乒乓)指示位置历史而不是非活动列表。

答案 1 :(得分:3)

使用索引视图在早于2008的SQL Server版本上实现“过滤索引”:

CREATE VIEW vOnlyOneActive
AS
  SELECT PersonID
  FROM <underlying table>
  WHERE Active = 1
GO
CREATE UNIQUE CLUSTERED INDEX IX_vOnlyOneActive on vOnlyOneActive (PersonID)
GO

您需要为此启用正确的ANSI settings

答案 2 :(得分:2)

约束不适用于多行,因此您需要INSERT/UPDATE trigger仅针对具有相同PersonIDLocationID的一组记录强制执行一条活动记录。

答案 3 :(得分:0)

从tblPerson到PersonID的外键引用,从tblLocation到LocationID,以及PersonId和LocationId上的联合键,以确保它们在一起是唯一的。