在 T-SQL 中,我遵循一个约束,该约束将阻止为该标志插入重复记录。
对于每个 [FK_Something],标志 [MyFlag]
只能设置为值 1 一次,但可以多次设置为 0。
这是否可能,并且在不使用触发器的情况下如何实现?
我使用的是 SQL Server 2008 R2。
set nocount on
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[MyTable]') AND type in (N'U'))
DROP TABLE [dbo].[MyTable]
GO
CREATE TABLE [dbo].[MyTable]
(
[id] [int] IDENTITY(1,1) NOT NULL,
[FK_Something] [int] NOT NULL,
[MyFlag] [bit] NOT NULL
) ON [PRIMARY]
GO
-- Valid inserts --
INSERT INTO [MyTable] ([FK_Something],[MyFlag]) VALUES (1,0);
INSERT INTO [MyTable] ([FK_Something],[MyFlag]) VALUES (1,1);
INSERT INTO [MyTable] ([FK_Something],[MyFlag]) VALUES (1,0);
INSERT INTO [MyTable] ([FK_Something],[MyFlag]) VALUES (2,0);
INSERT INTO [MyTable] ([FK_Something],[MyFlag]) VALUES (2,0);
INSERT INTO [MyTable] ([FK_Something],[MyFlag]) VALUES (2,0);
INSERT INTO [MyTable] ([FK_Something],[MyFlag]) VALUES (2,1);
---------------------------------------
-- Inserts Should Fail
-- As [MyFlag] set for [FK_Something]
---------------------------------------
INSERT INTO [MyTable] ([FK_Something],[MyFlag]) VALUES (1,1)
GO
INSERT INTO [MyTable] ([FK_Something],[MyFlag]) VALUES (2,1)
GO
-- Constraint should apply this logic --
Declare @FK_Something INT
Declare @MyFlag INT
set @FK_Something = 2
Set @MyFlag = 0
if( @myflag = 0 OR
not exists(Select 1 from [MyTable] where FK_Something = @FK_Something and MyFlag = @MyFlag))
BEGIN
INSERT INTO [MyTable] ([FK_Something],[MyFlag]) VALUES (@FK_Something,@MyFlag);
print 'Inserted ';
END
GO
select * from [MyTable]
最佳答案
指数。
For each [FK_Something] the flag [MyFlag] can only be set once to value 1 but can be set to 0 many times.
这是 1 个简单索引:
- FK_Something 和 MyFlag 1 - 独特
这里的技巧是不要对所有行应用唯一索引,这就是添加过滤器的原因。
http://msdn.microsoft.com/en-us/library/cc280372.aspx
解释如下语法:
CREATE UNIQUE NONCLUSTERED INDEX IX_Whatever
ON MyTable (FK_Something, myFlag)
WHERE MyFlag = 1
比约束更简单,并且保证有效。
关于sql - SQL Server 表上的唯一分组约束,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25740310/