SQL 업데이트 트리거에서 복제를 방지하기위한 제약 조건 추가
-
23-08-2019 - |
문제
사용자 테이블이 있으며 모든 사용자에게는 고유 한 이메일과 사용자 이름이 있습니다. 우리는 코드 내 에서이 작업을 수행하려고 노력하지만 동일한 사용자 이름의 이메일로 데이터베이스에 사용자가 삽입 (또는 업데이트)을받지 않도록하고 싶습니다. 나는 추가했다 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 INDEX
에 NVARCHAR
그 자리자 마자 NVARCHAR(450)
이하.
당신은 정말로 필요합니까? UNIQUE
칼럼이 너무 커요?
일반적으로 방아쇠가 존재한다는 것을 알지 않는 한 행동을 이해하기 어려울 수 있기 때문에 가능한 한 트리거를 피할 수 있습니다. 다른 주석 가운데서 말했듯이, 고유 한 제약은 갈 수있는 방법입니다 (일단 열 정의를 수정 한 후에는 그것을 허용합니다).
트리거를 사용해야한다면 디자인이 결함이 있다는 신호일 수 있습니다. 왜 필요한지와 다른 곳에 속한 논리를 수행하는지 여부에 대해 열심히 생각하십시오.
SQL Server와 함께 고유 한 구속 조건/색인 솔루션을 사용하면 해당 열에서 하나의 널 값만 허용됩니다. 예를 들어, 이메일 주소가 선택 사항이되기를 원한다면 한 명의 사용자 만 Null 이메일 주소를 가질 수 있으므로 작동하지 않습니다. 이 경우 트리거 나 필터링 된 인덱스와 같은 다른 접근 방식에 의지해야합니다.