Domanda

Ho una tabella che contiene solo due colonne: un ListID e PersonID. Quando una persona è unita a un'altra nel sistema, dovevo aggiornare tutti i riferimenti dalla "fonte" persona da fare riferimento alla "destinazione" persona.

Idealmente, vorrei chiamare qualcosa di semplice come

UPDATE MailingListSubscription
SET PersonID = @DestPerson
WHERE PersonID = @SourcePerson

Tuttavia, se la persona di destinazione esiste già in questa tabella con lo stesso ListID della persona di origine, verrà effettuata una voce duplicata. Come posso eseguire questa azione senza creare voci duplicate? (ListID, PersonID è la chiave primaria)

EDIT: vengono utilizzati più ListID. Se SourcePerson è assegnato a ListID 1, 2 e 3 e DestinationPerson è assegnato a ListID 3 e 4, il risultato finale deve avere quattro righe: DestinationPerson assegnato a ListID 1, 2, 3 e 4.

È stato utile?

Soluzione

--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

Altri suggerimenti

Per prima cosa dovresti iscrivere destperson a tutti gli elenchi a cui SourcePerson è abbonato che Destperson non è già iscritto. Quindi eliminare tutti gli abbonamenti SourcePersons. Funzionerà con più 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

Devo essere d'accordo con David B qui. Rimuovi tutte le cose meno recenti che non dovrebbero essere presenti e quindi esegui l'aggiornamento.

In realtà, penso che dovresti tornare indietro e riconsiderare la progettazione del tuo database come non dovresti essere in circostanze in cui stai cambiando la chiave primaria per un record come stai proponendo di fare - implica che la colonna PersonID non è in realtà una chiave primaria adatta in primo luogo.

Suppongo che il tuo PersonID sia esposto ai tuoi utenti, hanno rinumerato il loro database per qualche motivo e stai sincronizzando nuovamente il cambiamento. Questa è generalmente una cattiva idea in quanto interrompe le piste di controllo e la coerenza temporale. In queste circostanze, è generalmente meglio utilizzare la propria chiave primaria non modificabile, di solito un'identità, e impostare il PersonID che gli utenti vedono come un attributo di quello. È un lavoro extra ma ti darà ulteriore coerenza e robustezza nel lungo periodo.

Una buona regola empirica è che la chiave primaria di un record non dovrebbe essere esposta agli utenti dove possibile e dovresti farlo solo dopo un'attenta considerazione. OK, confesso di averlo rotto io stesso in numerose occasioni, ma vale la pena lottare per dove puoi :-)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top