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,请看我在你的答案中的评论,检查约束并不像你认为的那样有效。谢谢。我不知道过滤过的索引。我将使用这种方法。应用程序将防止坏数据,但这有利于保护和性能。我认为这种方法的好处是能够返回自定义消息。