두 열의 조합에 고유한 제약 조건 추가
테이블이 있는데 어떻게 된 일인지 같은 사람이 제 방에 들어와서Person
테이블을 두 번 누릅니다.현시점에서는 프라이머리 키는 자동번호에 불과하지만 다른 두 개의 필드가 존재합니다.
예를 들어 다음과 같은 필드가 있습니다.
ID
Name
Active
PersonNumber
고유 Person Number 및 Active = 1의 레코드가 하나만 필요합니다.
(따라서 두 필드의 조합은 고유해야 합니다.)
SQL Server의 기존 테이블에서 가장 좋은 방법은 기존 값과 동일한 값을 가진 삽입을 다른 사용자가 실행해도 실패하므로 애플리케이션 코드에서 이 문제를 걱정할 필요가 없습니다.
중복 항목을 삭제한 후:
ALTER TABLE dbo.yourtablename
ADD CONSTRAINT uq_yourtablename UNIQUE(column1, column2);
또는
CREATE UNIQUE INDEX uq_yourtablename
ON dbo.yourtablename(column1, column2);
물론 SQL Server에서 행을 삽입하고 예외를 반환하기 전에 먼저 이 위반을 확인하는 것이 좋습니다(예외는 비용이 많이 듭니다).
응용 프로그램을 변경하지 않고 응용 프로그램에 예외가 발생하는 것을 방지하려면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행 UNIQ KEY 제약 조건 'uq_Person' 위반.개체 'dbo'에 중복 키를 삽입할 수 없습니다.사람의.문이 종료되었습니다.
또한 다음 두 열에 고유한 제약을 적용하는 솔루션에 대해서도 블로그에 올렸습니다.
이것은 GUI에서도 실행할 수 있습니다.
- "사용자" 표에서 색인에서 마우스 오른쪽 단추를 누릅니다.
- 새 인덱스 클릭/이동
- [비클러스터 인덱스...]을 클릭합니다.
- 기본 인덱스 이름이 지정되지만 변경할 수도 있습니다.
- [ Check Unique ]체크박스
- [추가] 를 누릅니다.단추
- 포함할 열을 선택합니다.
- 각 창에서 [OK]을 클릭합니다.
내 경우 다음과 같이 많은 비활성화와 두 키의 한 조합만 활성화해야 했습니다.
UUL_USR_IDF UUL_UND_IDF UUL_ATUAL
137 18 0
137 19 0
137 20 1
137 21 0
이것은 효과가 있는 것 같습니다.
CREATE UNIQUE NONCLUSTERED INDEX UQ_USR_UND_UUL_USR_IDF_UUL_ATUAL
ON USER_UND(UUL_USR_IDF, UUL_ATUAL)
WHERE UUL_ATUAL = 1;
테스트 케이스는 다음과 같습니다.
SELECT * FROM USER_UND WHERE UUL_USR_IDF = 137
insert into USER_UND values (137, 22, 1) --I CAN NOT => Cannot insert duplicate key row in object 'dbo.USER_UND' with unique index 'UQ_USR_UND_UUL_USR_IDF_UUL_ATUAL'. The duplicate key value is (137, 1).
insert into USER_UND values (137, 23, 0) --I CAN
insert into USER_UND values (137, 24, 0) --I CAN
DELETE FROM USER_UND WHERE UUL_USR_ID = 137
insert into USER_UND values (137, 22, 1) --I CAN
insert into USER_UND values (137, 27, 1) --I CAN NOT => Cannot insert duplicate key row in object 'dbo.USER_UND' with unique index 'UQ_USR_UND_UUL_USR_IDF_UUL_ATUAL'. The duplicate key value is (137, 1).
insert into USER_UND values (137, 28, 0) --I CAN
insert into USER_UND values (137, 29, 0) --I CAN
삽입 쿼리가 많지만 매번 ERROR 메시지를 생성하지 않을 경우 다음을 수행할 수 있습니다.
CREATE UNIQUE NONCLUSTERED INDEX SK01 ON dbo.Person(ID,Name,Active,PersonNumber)
WITH(IGNORE_DUP_KEY = ON)
언급URL : https://stackoverflow.com/questions/15800250/add-unique-constraint-to-combination-of-two-columns
'programing' 카테고리의 다른 글
T-SQL에서 퍼센트 부호를 이스케이프하려면 어떻게 해야 하나요? (0) | 2023.04.07 |
---|---|
인덱스에서 열의 순서가 얼마나 중요합니까? (0) | 2023.04.07 |
SQL Server에서의 LIKE vs Contains (0) | 2023.04.07 |
SQL varchar에서 특정 하위 문자열의 발생 횟수를 어떻게 계산합니까? (0) | 2023.04.07 |
C#을 사용하여 텍스트에 탭 문자 삽입 (0) | 2023.04.07 |