문제

사용자 테이블이 있으며 모든 사용자에게는 고유 한 이메일과 사용자 이름이 있습니다. 우리는 코드 내 에서이 작업을 수행하려고 노력하지만 동일한 사용자 이름의 이메일로 데이터베이스에 사용자가 삽입 (또는 업데이트)을받지 않도록하고 싶습니다. 나는 추가했다 BEFORE INSERT 중복 사용자의 삽입을 방지하는 트리거.

CREATE TRIGGER [dbo].[BeforeUpdateUser]
   ON  [dbo].[Users]
   INSTEAD OF INSERT
AS 
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;

    DECLARE @Email nvarchar(MAX)
    DECLARE @UserName nvarchar(MAX)
    DECLARE @UserId int
    DECLARE @DoInsert bit

    SET @DoInsert = 1

    SELECT @Email = Email, @UserName = UserName FROM INSERTED

    SELECT @UserId = UserId FROM Users WHERE Email = @Email

    IF (@UserId IS NOT NULL)
        BEGIN
            SET @DoInsert = 0
        END

    SELECT @UserId = UserId FROM Users WHERE UserName = @UserName

    IF (@UserId IS NOT NULL)
        BEGIN
            SET @DoInsert = 0
        END

    IF (@DoInsert = 1)
        BEGIN
            INSERT INTO Users
            SELECT 
                           FirstName, 
                           LastName, 
                           Email, 
                           Password, 
                           UserName, 
                           LanguageId,
                           Data, 
                           IsDeleted 
                       FROM INSERTED
        END
    ELSE
        BEGIN
            DECLARE @ErrorMessage nvarchar(MAX)
            SET @ErrorMessage = 
                         'The username and emailadress of a user must be unique!'
            RAISERROR 50001 @ErrorMessage
        END 
END

그러나 업데이트 트리거의 경우 어떻게 해야하는지 전혀 모릅니다. 이 예제를 Google에서 찾았습니다.http://www.devarticles.com/c/a/sql-server/using-triggers-in-ms-sql-server/2/그러나 여러 열을 한 번에 업데이트 할 때 적용되는지 모르겠습니다.

편집하다:

이 열에 고유 한 제약 조건을 추가하려고했지만 작동하지 않습니다.

Msg 1919, Level 16, State 1, Line 1
Column 'Email' in table 'Users' is of a type 
that is invalid for use as a key column in an index.
도움이 되었습니까?

해결책

테이블에 고유 한 기부금을 추가 할 수 있습니다. 이렇게하면 중복을 시도하고 삽입하거나 업데이트하고 생성하면 오류가 발생합니다.

ALTER TABLE [Users] ADD  CONSTRAINT [IX_UniqueUserEmail] UNIQUE NONCLUSTERED 
(
    [Email] ASC
)

ALTER TABLE [Users] ADD  CONSTRAINT [IX_UniqueUserName] UNIQUE NONCLUSTERED 
(
    [UserName] ASC
)

편집 : 좋아, 나는 당신의 의견을 다른 게시물에 읽었고 당신이 nvarchar (max)를 데이터 유형으로 사용하고 있음을 알았습니다. 이메일 주소 나 사용자 이름을 위해 4000 개 이상의 문자를 원하는 이유가 있습니까? 이것은 당신의 문제가있는 곳입니다. 이것을 Nvarchar (250) 또는 그에 따라 줄이면 고유 한 색인을 사용할 수 있습니다.

다른 팁

하나 이상의 고유 한 인덱스를 사용하는 대신 많은 작업처럼 들립니다. 인덱스 경로를 사용하지 않은 이유가 있습니까?

데이터베이스의 열에서 고유 한 속성 만 사용하지 않겠습니까? SQL Server가이를 시행하고 Dupe를 삽입하려고하면 오류를 던지는 설정.

SQL을 사용해야합니다 UNIQUE 이 각 열의 제약 조건.

당신은 a를 만들 수 있습니다 UNIQUE INDEXNVARCHAR 그 자리자 마자 NVARCHAR(450) 이하.

당신은 정말로 필요합니까? UNIQUE 칼럼이 너무 커요?

일반적으로 방아쇠가 존재한다는 것을 알지 않는 한 행동을 이해하기 어려울 수 있기 때문에 가능한 한 트리거를 피할 수 있습니다. 다른 주석 가운데서 말했듯이, 고유 한 제약은 갈 수있는 방법입니다 (일단 열 정의를 수정 한 후에는 그것을 허용합니다).

트리거를 사용해야한다면 디자인이 결함이 있다는 신호일 수 있습니다. 왜 필요한지와 다른 곳에 속한 논리를 수행하는지 여부에 대해 열심히 생각하십시오.

SQL Server와 함께 고유 한 구속 조건/색인 솔루션을 사용하면 해당 열에서 하나의 널 값만 허용됩니다. 예를 들어, 이메일 주소가 선택 사항이되기를 원한다면 한 명의 사용자 만 Null 이메일 주소를 가질 수 있으므로 작동하지 않습니다. 이 경우 트리거 나 필터링 된 인덱스와 같은 다른 접근 방식에 의지해야합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top