SQL 服务器检查约束以防止特定重复
SQL Server check constraint to prevent specific duplicates
我有这样的数据结构:
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
一个用户只能拥有一个 status=1 的包。但是他们可以有很多 status=2 or status=3 or status=4.
谁能想出在 SQL 服务器中强制执行此规则的方法?
好吧,您可以自然地使用触发器,或者您可以使用唯一的过滤索引(如果您是 运行 SQL Server 2008 或更高版本),例如:
create unique index ix_tmp
on test_Bundles (UserId, status) where status = 1;
如果您更喜欢采用触发路线(这适用于任何合理版本的 SQL 服务器),它看起来像这样:
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;
create trigger trigPreventStatus1Duplicates
On test_Bundles for insert, update
as
declare @errMsg varchar(200) =
'You cannot enter more than one status 1 bundle per user.'
set NoCount On
begin
if exists (Select * from inserted i
join test_Bundles b
on b.userId = i.userId
and b.bundleId != i.bundleId
where b.status = 1
group by i.UserId
having count(*) > 1)
begin
rollback transaction
raiserror(errMsg , 16, 1)
end
end
我有这样的数据结构:
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
一个用户只能拥有一个 status=1 的包。但是他们可以有很多 status=2 or status=3 or status=4.
谁能想出在 SQL 服务器中强制执行此规则的方法?
好吧,您可以自然地使用触发器,或者您可以使用唯一的过滤索引(如果您是 运行 SQL Server 2008 或更高版本),例如:
create unique index ix_tmp
on test_Bundles (UserId, status) where status = 1;
如果您更喜欢采用触发路线(这适用于任何合理版本的 SQL 服务器),它看起来像这样:
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;
create trigger trigPreventStatus1Duplicates
On test_Bundles for insert, update
as
declare @errMsg varchar(200) =
'You cannot enter more than one status 1 bundle per user.'
set NoCount On
begin
if exists (Select * from inserted i
join test_Bundles b
on b.userId = i.userId
and b.bundleId != i.bundleId
where b.status = 1
group by i.UserId
having count(*) > 1)
begin
rollback transaction
raiserror(errMsg , 16, 1)
end
end