2013-11-20 2 views
7

주어진 다음의 표 (샘플 데이터) :SQL 서버 조건부 고유 색인

PK | ClientID | SetID | Title 
----------------------------- 
P1 | C1  | S1 | Title1 
P2 | C1  | S1 | Title1 
P3 | C2  | S2 | Title1 
P4 | C2  | S2 | Title1 
P3 | C1  | S3 | Title2 
P5 | C1  | S3 | Title2 

가정 할 Set 내가 고유 인덱스를 가질 수하는 Client에 속하는 제약을 제외하고 클라이언트 내의 단일의 제목을 그것은 동일한 세트 내의 형제 자매입니다.

예를 들어 Client에 두 개가 아닌 두 개에 Title1을 가질 수 있습니다. 이제 Client1의 경우 Title1이라는 두 번째 레코드가 필요하지만 다른 모든 레코드처럼 SetIDTitle 인 경우에만 해당 레코드를 보유하고 싶습니다.

저는 SQL Azure를 사용하고 있습니다 만, 더 일반적으로 관심이 있습니다 (예 : 2008 R2/2012).

편집 :
테이블 구조는 변경할 수 없습니다. 이 방법은 이미 존재하며 그 뒤에 복잡한 비즈니스 계층이 있습니다. 만약 내가 이것을 고칠 수 있다면, 그렇다면 크고, 그렇지 않다면, 깨뜨릴 수 있습니다. 내가 질문을 받았다면

+0

나는 당신의 고유 인덱스를해야 할 것 볼 수 없습니다 중복 된 정보를 허용하는 세 개의 열 인덱스의 일부가되기 위해 예를 들어 ID 열을 추가하는 경우에만이 문제가 해결 될 수 있다고 가정하지만 테이블을 변경할 수는 없습니다. – gotqn

+0

열을 추가 할 수는 있지만 테이블을 두 개로 분할하는 등의 변경을 할 수는 없습니다. –

+0

@gotqn. 고유 한 인덱스 일 필요는 없습니다. 그게 내가 속임수를 쓰고 있다고 생각한 것입니다. 단지 방법을 찾지 못했을뿐입니다! :) –

답변

2

추가 인덱싱 된보기를 시도 할 수 있습니다. 예를 들어

, 테이블 :

create table dbo.Test (PK int, ClientID int, SetID int, Title varchar(50), primary key (PK)) 

insert into dbo.Test values 
    (1, 1, 1, 'Title1') 
    ,(2, 1, 1, 'Title1') 
    ,(3, 2, 2, 'Title1') 
    ,(4, 2, 2, 'Title1') 
    ,(5, 1, 3, 'Title2') 
    ,(6, 1, 3, 'Title2') 

뷰 및 인덱스 :

create view dbo.vTest 
with schemabinding 
as 
    select ClientID, Title, SetID, cnt=count_big(*) 
    from dbo.Test 
    group by ClientID, Title, SetID 
GO 
create unique clustered index UX_vTest on dbo.vTest (ClientID, Title) 
GO 

다음 :

insert into dbo.Test values (7, 1, 1, 'Title1') -- will pass 
insert into dbo.Test values (8, 1, 1, 'Title1') -- will pass 
insert into dbo.Test values (9, 1, 2, 'Title1') -- will fail 
insert into dbo.Test values (10, 2, 2, 'Title1') -- will pass 
insert into dbo.Test values (11, 1, 3, 'Title1') -- will fail 
+0

이것이 내가 가장 고려하고있는 길입니다. 시간 내 줘서 고마워. –

0

바로 내가 어떻게 삽입/업데이트 트리거 상을 추가하는 방법에 대한 ClientID and SetID

CREATE UNIQUE INDEX [Index_Name] 
ON [dbo].[MyTable]([ClientID ], [SetID]) 
+0

조언 해 주셔서 감사합니다. 나는 그것이 더 나은 설정이 될 것이라고 동의하지만 불행히도 구조를 변경할 수있는 선택권이 없다. 내 옵션은 다음과 같습니다 : 열을 추가 (계산?), 색인,보기 등을 추가하십시오. –

0

에 고유 인덱스를 1:1 관계가있는 SetIDTitle 사이에 연결하고 추가 할 다른 테이블을 추가하는 검사를 수행하고 규칙 위반시 실패 예외를 발생시킵니다. 데이터 모델을 변경하지 않고도이를 추가 할 수 있습니다.

+0

나는 이것을 고려했지만 좀 더러운 느낌. 나는 BEFORE INSERT가 정말로 필요한 목적을 위해 AFTER INSERT DML 트리거를 사용하고 있습니다. 이 작업을 수행하기위한 방아쇠를 사용하는 것에 대한 우려는 성능입니다. 장단점을 제공 할 수 있습니까? –

+0

트리거를 사용할 수 있다면'INSTEAD OF INSERT' 트리거를 만들어 삽입을 처리하고 검사를 할 수 있습니다. – gotqn

+0

@gotgn 고마워, 나는 알고있다. 그러나 INSTEAD OF 트리거는 일어난 인서트를 다시 쓰도록 요구한다.내가 'INSERT INTO [테이블] SELECT * FROM INSERTED'를 할 수 있다면 행복 할거야.하지만 정체성으로는 그렇게 할 수 없다. –