0

UserID (int) UserName (nvarchar)、Password (nvarchar)、isActive (bit - true/false) という列を持つ Users というテーブルがあります。

私がやりたいことは、このユーザー名を持つ他のすべてのユーザーが無効になっている場合にのみ、重複したユーザー名の挿入を許可することです。

この関数を作成しました:

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 に答える