2

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

例如,一列最多Color只能记录 3 次?Blue

谢谢你。

4

3 回答 3

1

您可以使用存储过程来进行插入。在那里,您可以检查已经存在多少条记录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 
于 2012-12-18T16:37:42.230 回答
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);
于 2012-12-18T23:32:06.440 回答
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
于 2012-12-18T18:38:49.340 回答