Mesclando contatos na tabela SQL sem criar entradas duplicadas
-
02-07-2019 - |
Pergunta
Eu tenho uma tabela que contém apenas duas colunas - uma ListID e PersonID. Quando uma pessoa é mesclado com outro no sistema, eu estava para atualizar todas as referências da pessoa "fonte" para ser referências à pessoa "destino".
Idealmente, eu gostaria de chamar algo simples como
UPDATE MailingListSubscription
SET PersonID = @DestPerson
WHERE PersonID = @SourcePerson
No entanto, se a pessoa destino já existe nesta tabela com o mesmo ListID como a pessoa fonte, uma entrada duplicada será feita. Como posso executar esta ação, sem a criação de entradas duplicadas? (ListID, PersonID é a chave primária)
EDIT: Múltiplas ListIDs são usados. Se SourcePerson é atribuído a ListIDs 1, 2 e 3, e DestinationPerson é atribuído a ListIDs 3 e 4, em seguida, as necessidades resultado final ter quatro linhas -. DestinationPerson atribuído a ListID 1, 2, 3 e 4
Solução
--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
Outras dicas
Primeiro, você deve se inscrever destperson a todas as listas que SourcePerson está inscrito para que Destperson não estiver Subscritos. Em seguida, elimine todos os SourcePersons assinaturas. Isto irá trabalhar com vários ListIDs.
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
Eu tenho que concordar com David B aqui. Retirar todo o material mais antigo que não deveria estar lá e, em seguida, fazer a sua atualização.
Na verdade, eu acho que você deveria voltar atrás e reconsiderar seu projeto de banco de dados que você realmente não deve ser em circunstâncias em que você está mudando a chave primária para um registro de como você está propondo fazer - isso implica que a coluna PersonID não é realmente uma chave primária adequada em primeiro lugar.
Meu palpite é o seu PersonID está exposta a seus usuários, eles renumerado seu banco de dados por alguma razão e você está sincronizando o troco. Isso é geralmente uma má idéia como ele quebra as trilhas de auditoria e consistência temporal. Nestas circunstâncias, é geralmente melhor usar o seu próprio não-mudança de chave primária - normalmente uma identidade - e configurar o PersonID que os usuários vêem como um atributo do que isso. É um trabalho extra, mas vai dar-lhe consistência e robustez adicional no longo prazo.
Uma boa regra de ouro é a chave primária de um registro não deve ser exposto aos usuários sempre que possível e você só deve fazê-lo depois de cuidadosa consideração. OK, eu confesso a quebrar isso mesmo em numerosas ocasiões, mas vale a pena esforço para onde você pode :-)