2010-05-08 10 views
5

hey all. Ho una tabella nel mio DB che contiene circa un migliaio di record. Vorrei ripristinare la colonna Identity in modo che tutti gli ID siano di nuovo sequenziali. Stavo guardando this ma sto supponendo che funziona solo su un tavolo vuotoID di identità di reimpostazione SQL nella tabella già popolata

Tabella attuale

ID | Name 
1   Joe 
2   Phil 
5   Jan 
88   Rob 

tabella desiderata

ID | Name 
1   Joe 
2   Phil 
3   Jan 
4   Rob 

Grazie in anticipo

+0

La colonna Identity è utilizzata come chiave esterna altrove? – uhleeka

+0

no, è unico perché c'è un altro campo nella tabella che lo fa riferimento. –

+0

IE: 'ID | ParentID | Name' –

risposta

5

Il modo più semplice sarebbe quella di fare una copia della tabella corrente, sistemare eventuali problemi ParentID, cadere e quindi rinominare il nuovo.

Si potrebbe anche rimuovere temporaneamente il IDENTITY e provare il folowing:

;WITH TBL AS 
(
    SELECT *, ROW_NUMBER(ORDER BY ID) AS RN 
    FROM CURRENT_TABLE 
) 
UPDATE TBL 
SET ID = RN 

O, se non vi interessa circa l'ordine dei record, questo

DECLARE INT @id; 
SET @id = 0; 

UPDATE CURRENT_TABLE 
SET @id = ID = @id + 1; 
-2

Usa DBCC CHECKIDENT. la tabella non ha bisogno di essere vuoto:

  • DBCC CHECKIDENT (table_name, NORESEED)

valore Identity corrente non viene azzerato. DBCC CHECKIDENT restituisce il valore di identità attuale e il valore massimo corrente della colonna Identity. Se i due valori non corrispondono, è necessario che ripristini il valore di identità su per evitare potenziali errori o lacune nella sequenza di valori .

  • DBCC CHECKIDENT (table_name) o DBCC CHECKIDENT (table_name, RESEED)

Se il valore Identity corrente per una tabella è inferiore al valore massimo identità memorizzato nella colonna di identità , è ripristinato utilizzando il valore massimo nell'identità colonna.

  • DBCC CHECKIDENT (table_name, RESEED, new_reseed_value)

valore Identity corrente è impostato sul new_reseed_value. Se nessuna riga sono stati inserita nella tabella in quanto il tavolo è stato creato, o se tutte le righe sono state rimosse utilizzando l'istruzione TRUNCATE TABLE , la prima riga inserito dopo l'esecuzione DBCC CHECKIDENT utilizza new_reseed_value come l'identità. Altrimenti, la riga successiva inserita utilizza new_reseed_value + il valore di incremento attuale .

Se la tabella non è vuota, impostando il valore identità a un numero inferiore il valore massimo nell'identità colonna può comportare una delle seguenti condizioni:

  • Se un PRIMARIO Esiste un vincolo KEY o UNIQUE sull'identità colonna , il messaggio di errore 2627 sarà generato nelle operazioni di inserimento successivo nella tabella poiché il valore dell'identità generato sarà in conflitto con esistente valori.

  • Se un vincolo PRIMARY KEY o UNIQUE non esiste, in seguito operazioni di inserimento si tradurrà in valori di identità duplicati.

+0

Questo in realtà non funziona. Come dice l'articolo, se eseguo 'DBCC CHECKIDENT (table_name, RESEED, new_reseed_value)' allora non posso inserire nuovi record dove sono attualmente i vecchi record. Sembra che l'unico modo per farlo correttamente sia inserire i dati in una nuova tabella (ricreando gli ID), rilasciare la vecchia tabella e rinominare la nuova tabella con il nome della tabella precedente. –

+0

Questo cambierà il prossimo valore di inizializzazione dell'identità; non aggiornare i valori di identità esistenti. –

1

Soluzione rapida sarebbe a:

  1. creare una nuova tabella con lo stesso schema
  2. copiare la vecchia tabella a quello nuovo (fatta eccezione per la colonna Identity)
  3. eliminare la vecchia tabella di
  4. rinominare la nuova tabella
1

Perché hai chiavi esterne nella stessa tabella (per il tuo commento), sarà necessario conservare la mappatura da vecchio a nuovo da qualche parte e re-installare le chiavi esterne per abbinare le nuove identità.

Ci sono diversi approcci per farlo, ma vorrei fortemente mettere in dubbio la necessità di aggiornare le chiavi primarie, soprattutto perché hai già le chiavi esterne a farvi riferimento, ed è solo una chiave surrogata. Non è che stai cambiando la tua chiave surrogata a un GUID o qualcosa di speciale.

3

un modo, avvolgere questo in una transazione

select id,name into #temp from YourTable 

     truncate table YourTable 

     insert YourTable (name) 
     select name from #temp 
+0

molto bello! elegante e semplice. – uhleeka

+0

ma non risolve il tuo ParentID. – mdma

+4

non c'era nulla di parentid nella domanda quando ho risposto – SQLMenace

0

Ecco come ho ripristinato i campi di identità. La versione precedente di CTE (Common Table Expression) è overkill. Basta usare il numero di riga corrente per aggiornare la colonna di identità con una dichiarazione di aggiornamento semplice, con un join:

UPDATE [YourTable] SET ID = rn.RowNumber FROM [YourTable] 
JOIN (SELECT ID, ROW_NUMBER() OVER (ORDER BY ID) AS RowNumber 
    FROM [YourTable]) rn ON rn.ID = [YourTable].ID 

Questa affermazione può essere riscritta per essere ancora più semplice. Se è così, mi piacerebbe vedere la versione più semplice.

Spero che questo aiuti qualcuno.

Problemi correlati