중복을 제거하면 :
ALTER TABLE dbo.yourtablename
ADD CONSTRAINT uq_yourtablename UNIQUE(column1, column2);
또는
CREATE UNIQUE INDEX uq_yourtablename
ON dbo.yourtablename(column1, column2);
물론 SQL Server에서 행을 삽입하고 예외를 반환하기 전에 (예외가 비싸기)이 위반을 먼저 확인하는 것이 더 좋습니다.
http://www.sqlperformance.com/2012/08/t-sql-queries/error-handling
http://www.mssqltips.com/sqlservertip/2632/checking-for-potential-constraint-violations-before-entering-sql-server-try-and-catch-logic/
응용 프로그램을 변경하지 않고 응용 프로그램에 예외가 발생하지 않도록하려면 INSTEAD OF트리거를 사용할 수 있습니다.
CREATE TRIGGER dbo.BlockDuplicatesYourTable
ON dbo.YourTable
INSTEAD OF INSERT
AS
BEGIN
SET NOCOUNT ON;
IF NOT EXISTS (SELECT 1 FROM inserted AS i
INNER JOIN dbo.YourTable AS t
ON i.column1 = t.column1
AND i.column2 = t.column2
)
BEGIN
INSERT dbo.YourTable(column1, column2, ...)
SELECT column1, column2, ... FROM inserted;
END
ELSE
BEGIN
PRINT 'Did nothing.';
END
END
GO
그러나 사용자에게 삽입을 수행하지 않았다고 알리지 않으면 왜 데이터가없고 예외가보고되지 않았는지 궁금해 할 것입니다.
여기 편집 은 질문과 동일한 이름을 사용하여 요구 사항을 정확하게 수행하고 증명하는 예입니다. 위의 아이디어가 조합이 아닌 하나의 열만 처리한다고 가정하기 전에 시도해야합니다 ...
USE tempdb;
GO
CREATE TABLE dbo.Person
(
ID INT IDENTITY(1,1) PRIMARY KEY,
Name NVARCHAR(32),
Active BIT,
PersonNumber INT
);
GO
ALTER TABLE dbo.Person
ADD CONSTRAINT uq_Person UNIQUE(PersonNumber, Active);
GO
-- succeeds:
INSERT dbo.Person(Name, Active, PersonNumber)
VALUES(N'foo', 1, 22);
GO
-- succeeds:
INSERT dbo.Person(Name, Active, PersonNumber)
VALUES(N'foo', 0, 22);
GO
-- fails:
INSERT dbo.Person(Name, Active, PersonNumber)
VALUES(N'foo', 1, 22);
GO
이 모든 후 테이블의 데이터 :
ID Name Active PersonNumber
---- ------ ------ ------------
1 foo 1 22
2 foo 0 22
마지막 삽입시 오류 메시지 :
메시지 2627, 수준 14, 상태 1, 줄 3 고유 키 제약 조건 'uq_Person'위반 개체 'dbo.Person'에 중복 키를 삽입 할 수 없습니다. 그 진술서는 만료되었습니다.