programing

두 열의 조합에 고유한 제약 조건 추가

skycolor 2023. 4. 7. 21:05
반응형

두 열의 조합에 고유한 제약 조건 추가

테이블이 있는데 어떻게 된 일인지 같은 사람이 제 방에 들어와서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에서도 실행할 수 있습니다.

  1. "사용자" 표에서 색인에서 마우스 오른쪽 단추를 누릅니다.
  2. 인덱스 클릭/이동
  3. [비클러스터 인덱스...]을 클릭합니다.

여기에 이미지 설명 입력

  1. 기본 인덱스 이름이 지정되지만 변경할 수도 있습니다.
  2. [ Check Unique ]체크박스
  3. [추가] 를 누릅니다.단추

여기에 이미지 설명 입력

  1. 포함할 열을 선택합니다.

여기에 이미지 설명 입력

  1. 각 창에서 [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

반응형