Sql server 防止特定重复的SQL Server检查约束

Sql server 防止特定重复的SQL Server检查约束,sql-server,indexing,constraints,Sql Server,Indexing,Constraints,我的数据结构如下: CREATE TABLE test_Bundles ( BundleId INT, UserId INT, status INT ) INSERT INTO test_Bundles VALUES (1, 1, 1) INSERT INTO test_Bundles VALUES (2, 1, 3) INSERT INTO test_Bundles VALUES (3, 1, 3) INSERT INTO test_Bundles VALUES (4,

我的数据结构如下:

CREATE TABLE test_Bundles 
(
   BundleId INT,
   UserId INT,
   status INT
)

INSERT INTO test_Bundles VALUES (1, 1, 1)
INSERT INTO test_Bundles VALUES (2, 1, 3)
INSERT INTO test_Bundles VALUES (3, 1, 3)
INSERT INTO test_Bundles VALUES (4, 2, 1)
INSERT INTO test_Bundles VALUES (5, 2, 3)
INSERT INTO test_Bundles VALUES (6, 2, 3)
GO
create trigger tgrTmp on test_Bundles for insert, update 
as
begin;

if exists(  select  * 
            from test_Bundles t
            join inserted i 
            on t.UserId = i.UserId
            and t.BundleId != i.BundleId
            where t.status = 1 
            and i.status = 1)
begin;
    raiserror ('unique violation',16,1);
    rollback;
end;

end;
一个用户只能有一个状态为1的捆绑包。但他们可以拥有状态为2或状态为3或状态为4的地块


有人能想出一种在SQL Server中实施此规则的方法吗?

好的,您可以自然地使用触发器,也可以使用唯一的筛选索引(如果您运行的是SQL Server 2008或更高版本),例如:

create unique index ix_tmp 
on test_Bundles (UserId, status) where status = 1;
如果您更愿意采用触发器路由(这将适用于任何合理版本的SQL Server),它将如下所示:

CREATE TABLE test_Bundles 
(
   BundleId INT,
   UserId INT,
   status INT
)

INSERT INTO test_Bundles VALUES (1, 1, 1)
INSERT INTO test_Bundles VALUES (2, 1, 3)
INSERT INTO test_Bundles VALUES (3, 1, 3)
INSERT INTO test_Bundles VALUES (4, 2, 1)
INSERT INTO test_Bundles VALUES (5, 2, 3)
INSERT INTO test_Bundles VALUES (6, 2, 3)
GO
create trigger tgrTmp on test_Bundles for insert, update 
as
begin;

if exists(  select  * 
            from test_Bundles t
            join inserted i 
            on t.UserId = i.UserId
            and t.BundleId != i.BundleId
            where t.status = 1 
            and i.status = 1)
begin;
    raiserror ('unique violation',16,1);
    rollback;
end;

end;

只有当check constraint选项不存在时才应该选择触发器,就像在
MySQL
中一样。这完全是一个糟糕的建议。@Rahul,请看我在你的答案中的评论,检查约束并不像你认为的那样有效。谢谢。我不知道过滤过的索引。我将使用这种方法。应用程序将防止坏数据,但这有利于保护和性能。我认为这种方法的好处是能够返回自定义消息。