限制可以在列中输入唯一值的次数

时间:2012-12-18 16:29:29

标签: sql-server sql-server-2012

我正在学习使用SQL Server 2012,我想知道将columm限制为仅允许每个值输入最大次数的最佳方法是什么?

E.g。列Color只允许Blue最多录制三次?

谢谢。

3 个答案:

答案 0 :(得分:1)

您可以使用stored-procedure进行插入。在那里,您可以查看Color = 'Blue'已存在的记录数。

CREATE PROCEDURE sp_InsertColor @Color nvarchar(30), @ColorCount int OUTPUT
AS
BEGIN TRANSACTION

SELECT @ColorCount = count(*) 
FROM dbo.ColorTable
WHERE Color = @Color

IF @ColorCount <= 3 
BEGIN
    INSERT INTO dbo.ColorTable(COLOR) VALUES(@Color);
END

COMMIT
GO

您可以这样执行:

DECLARE @ColorCount int
EXEC sp_InsertColor @Color = 'Blue', @ColorCount = @ColorCount OUTPUT
SELECT @ColorCount 

答案 1 :(得分:1)

使用约束约束您的数据,并为(强制)罕见的实例留下触发器,您必须在数据库中实现业务逻辑(当插入新颜色时,执行xyz)

这是一种基于约束的方式,使用绑定到检查的函数:

--setup
create table dbo.Color (ColorId int primary key, ColorName varchar(10), Cap int);
go
create table dbo.Detail (DetailId int identity(1,1), ColorId int references dbo.Color(ColorId));
go

--create color blue with max row cap of 3
insert into dbo.Color
    values(1, 'blue', 3);
go

--create a func to evaluate the max row cap 
create function dbo.IsColorCapped(@ColorId int)
returns bit
as
begin
    return  (   select  case when count(*) > max(c.Cap) then 1 else 0 end
                from    dbo.Color c 
                join    dbo.Detail d on 
                        c.ColorId = d.ColorId
                where   c.ColorId = @ColorId
            )
end;
go

-- use the func in table constraint
alter table dbo.Detail add constraint ck_ColorCap check (dbo.IsColorCapped(ColorId)=0);
go

-- Test...

-- insert 3 blue rows
insert into dbo.Detail (ColorId)
    values(1),(1),(1);

-- insert 4th blue row - FAIL
insert into dbo.Detail (ColorId)
    values(1)
/*
Msg 547, Level 16, State 0, Line 1
The INSERT statement conflicted with the CHECK constraint "ck_ColorCap". The conflict occurred in database "yak", table "dbo.Detail", column 'ColorId'.
The statement has been terminated.
*/

-- incease the color cap
update dbo.Color
set Cap = 4
where ColorId = 1;

-- insert 4th blue row again
insert into dbo.Detail (ColorId)
    values(1);

答案 2 :(得分:0)

此线程中提到的存储过程方法将起作用,但只有在执行插入的所有内容中使用它时才有效。更好的方法是使用类似的逻辑在触发器中强制执行它。触发器将保证规则的执行。检查触发器中插入颜色的计数,如果它等于最大计数,则挽救。不要忘记检查更新,而不仅仅是插入。

Create TRIGGER [dbo].[ColorTableTrigger] ON [dbo].[ColorTable] 
FOR  Insert 
AS
DECLARE @colorCount int
begin
SELECT @ColorCount = count(*) 
FROM dbo.ColorTable
WHERE Color = inserted.color


If @colorCount = 3  (
        rollback tran
    RAISERROR <some user defined error>
    )
end
end