0

我有一个名为 Users 的表,其中包含以下列:UserID (int) UserName (nvarchar)、Password (nvarchar)、isActive (bit - true/false)。

我想要做的是仅当所有其他具有此用户名的用户都被禁用时才允许插入重复的用户名。

我创建了这个函数:

ALTER FUNCTION [dbo].[isActiveUsername]
    (@username nvarchar(15))
RETURNS bit
AS

BEGIN

IF EXISTS
            (
                SELECT * 
                FROM Users
                WHERE isActive = 1 AND UserName = @username
            )
            RETURN 1
    RETURN 0
END

如果有使用此用户名的活动用户,此函数将返回 true,否则返回 false。

之后,我根据该函数的返回值创建了检查约束:

ALTER TABLE [dbo].[Users]  
WITH NOCHECK ADD CHECK  (([dbo].[isActiveUsername]([UserName])=(0)))

如果没有具有此用户名的活动用户,则允许插入...但是由于某种原因,当我尝试插入新用户时,无论我尝试使用什么用户名,我都会收到此错误:

Msg 547, Level 16, State 0, Line 2
The INSERT statement conflicted with the CHECK constraint "CK__Users__UserName__4D94879B". The conflict occurred in database "Chat", table "dbo.Users", column 'UserName'.
The statement has been terminated.

请帮忙?非常感谢!!

4

2 回答 2

3

对于 MSSQL 2008 及更高版本,在 isActive 上创建过滤索引:

create unique index ux_UserName on dbo.Users(Username) where isActive = 1;

这允许您对数据子集强制执行唯一性。

于 2014-10-10T15:57:31.273 回答
0

问题是INSERT在你的CHECK约束运行之前发生,所以在函数运行之前表中总是有一个用户。将您的功能更改为:

ALTER FUNCTION [dbo].[isActiveUsername]
    (@username nvarchar(15))
RETURNS bit
AS
BEGIN
    IF  (SELECT COUNT(*) FROM Users WHERE isActive = 1 AND UserName = @username) > 1
    BEGIN
        RETURN 1
    END

    RETURN 0

END
于 2014-10-10T15:57:14.067 回答