2010-07-05 15 views
6

voglio cambiare il valore della chiave primaria per una riga in una tabella che ha rapporti con altre tabelle:SQL Server: cambiare chiave primaria con righe correlate

Per esempio

Table Person { Id, Name, +50 fields } 
Table Address { Id, City, +10 fields } 
Table Person2Address { Id, PersonId, AddressId } 

voglio cambiare Person.Id e Person2Address.PersonId

cerco qualcosa di simile:

BEGIN TRANSACTION  
    UPDATE Pers SET Id = NewId WHERE Id = OldId 
    UPDATE Person2Address SET PersonId = NewId WHERE PersonId = OldId 
COMMIT TRANSACTION 

Ma naturalmente fornisce conflitti :)

Come posso temporaneamente sopprimere i vincoli di chiave esterna o c'è un modo migliore per cambiare l'ID per persona?

risposta

4

Prima di tutto, la modifica del valore della chiave primaria non è mai una buona idea. Il tuo obiettivo principale dovrebbe essere quello di cercare di evitarlo con tutti i mezzi.

Se non è possibile eliminare la necessità di aggiornare il valore della chiave primaria, la soluzione migliore sarebbe definire la relazione di chiave esterna tra queste due tabelle utilizzando ON UPDATE CASCADE, in modo che eventuali modifiche alla chiave primaria della tabella principale siano automaticamente a cascata verso il basso nella tabella figlio.

Per fare questo, rilasciare il rapporto di chiave esterna esistente e quindi aggiungere:

ALTER TABLE dbo.Person2Address 
    ADD CONSTRAINT FK_Person2Address_Person 
    FOREIGN KEY (PersonId) REFERENCES dbo.Person(Id) 
    ON UPDATE CASCADE 

Questo dovrebbe quindi aggiornare automaticamente il valore della tabella Person2AddressPersonId se il Id sulla persona cambiamenti.

Ora si dovrebbe essere in grado di chiamare solo

UPDATE dbo.Person SET Id = NewId WHERE Id = OldId 

e che dovrebbe essere tutto quello che c'è!

+3

Codice mal testato {0000-0000-0000} valore guida come PK, quindi voglio cambiarlo. Grazie, proverò –

2

La cosa più semplice per cose come questa è quello di usare qualcosa come:

BEGIN TRANSACTION  
    UPDATE Pers SET tempId = NewId WHERE Id = OldId 
    UPDATE Person2Address SET tempPersonId = NewId WHERE PersonId = OldId 
COMMIT TRANSACTION 

Poi rilasciare i campi ID e PersonID e rinominare quelli temporanei.

+0

Grazie per la risposta, ma sembra che l'approccio di @marc_s sia più semplice –

1

È possibile eliminare i vincoli FK e ricrearli al termine.

ALTER TABLE some_table DROP CONSTRAINT my_constraint 

Verificare articolo this per la creazione e la modifica dei vincoli.

+0

Grazie per l'articolo –

Problemi correlati