복붙노트

[SQL] 조건 고유 제한 조건

SQL

조건 고유 제한 조건

난 내가 열 집합에 고유 제한 조건을 적용해야하는 상황을 가지고 있지만, 컬럼의 하나 개의 값.

그래서 예를 들어 나는 표 (ID, 이름, RecordStatus)과 같은 테이블이 있습니다.

RecordStatus는 1 또는 2 (활성 또는 삭제) 값을 가질 수 있고, 나는 같은 여러 삭제 된 레코드가있는 경우 RecordStatus = 1, 난 상관하지 않기 때문에 때에 만의 고유 제한 조건 (ID, RecordStatus)를 만들려면 신분증.

외에도 트리거를 작성에서, 나는 그렇게 할 수 있습니까?

나는 SQL 서버 2005을 사용하고 있습니다.

해결법

  1. ==============================

    1.이 같은 점검 제한 조건을 추가합니다. 차이점은 거짓 돌아갑니다 인 경우 상태 = 1, 카운트> 0.

    이 같은 점검 제한 조건을 추가합니다. 차이점은 거짓 돌아갑니다 인 경우 상태 = 1, 카운트> 0.

    http://msdn.microsoft.com/en-us/library/ms188258.aspx

    CREATE TABLE CheckConstraint
    (
      Id TINYINT,
      Name VARCHAR(50),
      RecordStatus TINYINT
    )
    GO
    
    CREATE FUNCTION CheckActiveCount(
      @Id INT
    ) RETURNS INT AS BEGIN
    
      DECLARE @ret INT;
      SELECT @ret = COUNT(*) FROM CheckConstraint WHERE Id = @Id AND RecordStatus = 1;
      RETURN @ret;
    
    END;
    GO
    
    ALTER TABLE CheckConstraint
      ADD CONSTRAINT CheckActiveCountConstraint CHECK (NOT (dbo.CheckActiveCount(Id) > 1 AND RecordStatus = 1));
    
    INSERT INTO CheckConstraint VALUES (1, 'No Problems', 2);
    INSERT INTO CheckConstraint VALUES (1, 'No Problems', 2);
    INSERT INTO CheckConstraint VALUES (1, 'No Problems', 2);
    INSERT INTO CheckConstraint VALUES (1, 'No Problems', 1);
    
    INSERT INTO CheckConstraint VALUES (2, 'Oh no!', 1);
    INSERT INTO CheckConstraint VALUES (2, 'Oh no!', 2);
    -- Msg 547, Level 16, State 0, Line 14
    -- The INSERT statement conflicted with the CHECK constraint "CheckActiveCountConstraint". The conflict occurred in database "TestSchema", table "dbo.CheckConstraint".
    INSERT INTO CheckConstraint VALUES (2, 'Oh no!', 1);
    
    SELECT * FROM CheckConstraint;
    -- Id   Name         RecordStatus
    -- ---- ------------ ------------
    -- 1    No Problems  2
    -- 1    No Problems  2
    -- 1    No Problems  2
    -- 1    No Problems  1
    -- 2    Oh no!       1
    -- 2    Oh no!       2
    
    ALTER TABLE CheckConstraint
      DROP CONSTRAINT CheckActiveCountConstraint;
    
    DROP FUNCTION CheckActiveCount;
    DROP TABLE CheckConstraint;
    
  2. ==============================

    2.보라, 필터링 된 인덱스입니다. 문서 (강조 광산)에서 :

    보라, 필터링 된 인덱스입니다. 문서 (강조 광산)에서 :

    그리고 여기에 필터 조건과 고유 인덱스를 결합하는 예입니다 :

    create unique index MyIndex
    on MyTable(ID)
    where RecordStatus = 1;

    RecordStatus가 1 인 경우는 본질적 ID의 고유성을 적용.

    참고 : 필터링 된 인덱스는 SQL Server의 이전 버전의 SQL Server 2008의 도입,이 답변을 참조하시기 바랍니다.

  3. ==============================

    3.당신은 제약이 부족 테이블에 삭제 된 레코드를 이동, 아마도 단일 테이블의 모양을 유지하기 위해 두 테이블의 UNION과 뷰를 사용할 수 있습니다.

    당신은 제약이 부족 테이블에 삭제 된 레코드를 이동, 아마도 단일 테이블의 모양을 유지하기 위해 두 테이블의 UNION과 뷰를 사용할 수 있습니다.

  4. ==============================

    4.당신은 정말 해키 방법으로이 작업을 수행 할 수 있습니다 ...

    당신은 정말 해키 방법으로이 작업을 수행 할 수 있습니다 ...

    테이블에 스키마 바운드 뷰를 생성합니다.

    VIEW 무엇이든을 CREATE 테이블에서 SELECT * WHERE RecordStatus = 1

    이제 당신이 원하는 필드 뷰에 고유 제약 조건을 만들 수 있습니다.

    당신이 기본 테이블을 변경하면 스키마 바인딩 뷰에 대한 하나의 참고 사항,하지만 당신은보기를 다시 만들어야합니다. 그 때문에 개는 많이.

  5. ==============================

    5.당신은 중복을 허용하려고하는, 때문에, 고유 제한 조건이 작동하지 않습니다. 당신은 INSERT에 대한 RecordStatus 컬럼에 대한 점검 제한 조건 및 저장 프로 시저를 만들 수 검사 중복 ID를 삽입하기 전에 기존의 활성 기록.

    당신은 중복을 허용하려고하는, 때문에, 고유 제한 조건이 작동하지 않습니다. 당신은 INSERT에 대한 RecordStatus 컬럼에 대한 점검 제한 조건 및 저장 프로 시저를 만들 수 검사 중복 ID를 삽입하기 전에 기존의 활성 기록.

  6. ==============================

    6.빌의 제안으로 당신이 RecordStatus로 NULL을 사용할 수없는 경우, 당신은 함수 기반 인덱스와 함께 자신의 아이디어를 결합 할 수 있습니다. RecordStatus 당신이 당신의 제약 (와 달리 RecordStatus)에서 고려하고 그 이상의 인덱스를 작성하려는 값 중 하나가 아닌 경우 반환 NULL하는 함수를 만듭니다.

    빌의 제안으로 당신이 RecordStatus로 NULL을 사용할 수없는 경우, 당신은 함수 기반 인덱스와 함께 자신의 아이디어를 결합 할 수 있습니다. RecordStatus 당신이 당신의 제약 (와 달리 RecordStatus)에서 고려하고 그 이상의 인덱스를 작성하려는 값 중 하나가 아닌 경우 반환 NULL하는 함수를 만듭니다.

    즉, 명시 적으로 당신에게 성능 문제가 발생할 수 있습니다 귀하의 제약에서 테이블의 다른 행을 검사 할 필요가 없다는 장점이 있습니다.

    나는 모두에서 SQL 서버를 모르는 말을해야하지만 성공적으로 오라클에서이 방법을 사용했다.

  7. from https://stackoverflow.com/questions/866061/conditional-unique-constraint by cc-by-sa and MIT license