2008-09-25 4 views
1

ListID와 PersonID라는 두 개의 열만있는 테이블이 있습니다. 어떤 사람이 시스템에서 다른 사람과 합병되었을 때 나는 "대상자"의 모든 참조를 "대상자"에 대한 참조로 업데이트해야했습니다.중복 된 항목을 만들지 않고 SQL 테이블에 연락처 병합

적으로는, 내가 대상 사람이 이미 중복 된 항목이 될 것이다 소스 사람과 같은 ListID이 테이블에 존재하는 경우,

그러나
UPDATE MailingListSubscription 
SET PersonID = @DestPerson 
WHERE PersonID = @SourcePerson 

처럼 간단한 무언가를 호출하고 싶습니다. 중복 된 항목을 만들지 않고이 작업을 수행하려면 어떻게해야합니까? (ListID, PersonID는 기본 키입니다.)

EDIT : 여러 ListID가 사용됩니다. SourcePerson이 ListID 1, 2 및 3에 할당되고 DestinationPerson이 ListID 3 및 4에 할당 된 경우 최종 결과에는 ListID 1, 2, 3 및 4에 지정된 DestinationPerson의 4 개의 행이 있어야합니다.

답변

3
--out with the bad 
DELETE 
FROM MailingListSubscription 
WHERE PersonId = @SourcePerson 
    and ListID in (SELECT ListID FROM MailingListSubscription WHERE PersonID = @DestPerson) 

--update the rest (good) 
UPDATE MailingListSubscription 
SET PersonId = @DestPerson 
WHERE PersonId = @SourcePerson 
+0

보다 나은 성능이 존재합니다. 대신 –

+1

쿼리 분석기에 모두 씁니다. 실행 계획을 보았습니다. 동일한 계획을 보여주었습니다. "있음"대 "있음"은 중요하지 않습니다. PersonId에 대한 색인이 크게 중요합니다. –

0

여기 David B와 동의해야합니다. 없어야 할 모든 오래된 항목을 제거한 다음 업데이트하십시오.

0

실제로 나는 당신이 제안한 것처럼 레코드의 기본 키를 변경하는 상황에 있어서는 안되기 때문에 돌아가서 데이터베이스 디자인을 재고해야한다고 생각합니다. 이는 PersonID 열은 실제로 처음부터 적절한 기본 키가 아닙니다.

내 생각 엔 PersonID가 사용자에게 노출되어있어 어떤 이유로 든 데이터베이스의 번호를 다시 지정하고 변경 사항을 다시 동기화하는 것입니다. 일반적으로 감사 추적 및 일시적 일관성이 깨지면 좋지 않습니다. 이러한 상황에서는 일반적으로 사용자가 변경하지 않는 기본 키 (대개 ID)를 사용하고 사용자가 볼 수있는 PersonID를 속성으로 설정하는 것이 좋습니다. 추가 작업이지만 장기적으로 일관성과 견고 함을 제공합니다.

레코드의 기본 키는 가능하면 사용자에게 노출되어서는 안되며 신중하게 고려한 후에 만 ​​사용해야합니다. OK 나는 여러 차례 자신을 깨뜨리는 것에 대해 고백하지만 다음과 같이 할 수있는 곳에서 노력해야 할 가치가 있습니다 :-)

+0

나는 이것이 사실이라고 생각하지 않는다. 데이터 입력 점원이 시스템에서 Bill Smith를 찾지 못하는 것만 큼 간단 할 수 있습니다. (윌리엄 스미스와 마찬가지로) 새로운 항목이 만들어졌습니다. 오류는 나중에 발견되므로 Bill과 William Smith가 병합됩니다. 두 경우 모두 DB가 ID를 자동 생성했습니다. – JeremyDWill

0

먼저 DestPerson이 아직 subscibed되지 않은 SourcePerson이 구독하는 모든 목록에 destperson을 등록해야합니다. 그런 다음 모든 SourcePersons 구독을 삭제하십시오. 여러 ListID와 함께 작동합니다.

Insert into MailingListSubscription 
(
    ListID, 
    PersonID 
) 
Select 
    ListID, 
    @DestPerson 
From 
    MailingListSubscription as t1 
Where 
    PersonID = @SourcePerson and 
    Not Exists 
    (
     Select * 
     From MailingListSubscription as t2 
     Where 
     PersonID = @DestPerson and 
     t1.ListID = t2.ListID 
    ) 



Delete From MailingListSubscription 
Where 
    PersonID = @SourcePerson 
관련 문제