Ripristina AutoIncrement in SQL Server dopo Elimina


266

Ho eliminato alcuni record da una tabella in un database di SQL Server. Ora gli ID vanno da 101 a 1200. Voglio cancellare di nuovo i record, ma voglio che gli ID tornino a 102. C'è un modo per farlo in SQL Server?


46
Per favore, non dire "Non farlo". Lo odio quando chiedo come fare qualcosa e tutto ciò che ottengo è no. Sì, il ripristino dell'identità può causare problemi di chiave esterna, ma solo se non si conosce il database e il programma di conseguenza. Ci sono ottime ragioni per ripristinare un'identità dopo un'eliminazione programmata: si chiamano revisori. I revisori odiano vedere lacune, quindi colmatele, fatele in modo controllato e assicuratevi che vengano mantenute le controindicazioni delle chiavi esterne.

6
@spyder, sapevi che avresti delle lacune se un inserimento record viene eseguito il rollback non solo per l'eliminazione? Non puoi evitare le lacune con un aumento automatico ed è sciocco da provare. Ho lavorato per un'agenzia di revisione contabile e i revisori competenti possono spiegarglielo. Inoltre, se si dispone di tabelle di controllo appropriate, possono vedere cosa è successo a tali record. O se non devono esserci mai lacune per motivi legali (ce ne sono alcuni casi), solo uno sviluppatore incompetente userebbe un incremento automatico e i revisori sono giustamente arrabbiati.
HLGEM,

Risposte:


456

Immettere il comando seguente per ridimensionare mytable per iniziare da 1:

DBCC CHECKIDENT (mytable, RESEED, 0)

Leggi a riguardo nella documentazione on line (BOL, guida di SQL). Fai anche attenzione a non avere record più alti del seme che stai impostando.


4
... perché gli ID di questi record verranno felicemente riutilizzati di nuovo, causando un brutto pasticcio.
inalterato il

3
In realtà, per avviare gli ID da 1, devi usare 0: DBCC CHECKIDENT (mytable, RESEED, 0)
Ryan Lundy

7
"DBCC CHECKIDENT (table_name)" imposta il seme sull'identità più alta nella tabella, che non devi "stare attento"
user1027167

4
@ user1027167 No, la tua risposta non ha funzionato per me. Continuava ad aumentare sull'ID più alto che aveva salvato internamente. Ho dovuto usare esplicitamente "RESEED, 18" nel mio caso per ottenere "19" come ID successivo. Senza di essa continuava felicemente ad aumentare su "29".
Matthis Kohli,

DBCC CHECKIDENT (table_name) cambia il seme solo se il valore dell'identità è inferiore al valore massimo nella colonna. Quindi, se il valore dell'identità è già maggiore come nel caso di @MhishisKohli, deve essere chiamato il resed esplicito.
Martheen,

82
DBCC CHECKIDENT('databasename.dbo.tablename', RESEED, number)

se numero = 0, nel successivo inserimento il campo di incremento automatico conterrà il valore 1

se numero = 101, nel successivo inserimento il campo di incremento automatico conterrà il valore 102


Alcune informazioni aggiuntive ... Potrebbe esserti utile

Prima di fornire l'incremento automatico numbernella query precedente, devi assicurarti che la colonna di incremento automatico della tabella esistente contenga valori inferiori number.

Per ottenere il valore massimo di una colonna (nome_colonna) da una tabella (tabella1), è possibile utilizzare la seguente query

 SELECT MAX(column_name) FROM table1

37

semi idiota:

declare @max int;  
select @max = max(key) from table;  
dbcc checkident(table,reseed,@max)

http://sqlserverplanet.com/tsql/using-dbcc-checkident-to-reseed-a-table-after-delete


1
"DBCC CHECKIDENT (table_name)" fa lo stesso (possibile senza condizioni di gara)
user1027167

2
@ user1027167 I documenti dicono "se il valore di identità corrente per una tabella è inferiore al valore di identità massimo memorizzato nella colonna identità"; che non copre la pulizia dopo l'eliminazione dei dati (riutilizzo degli ID, spesso una cattiva idea). Verificato su SQL 2008
user423430

1
La migliore risposta sistematica e automatica. Bravo!
Mehdi Khademloo,

11

Se stai usando MySQL, prova questo:

ALTER TABLE tablename AUTO_INCREMENT = 1

3
Questa è una risposta per MySQL. OP chiede informazioni su MSSQL.
riformato il

la domanda riguarda MS SQL Server
Saher Ahwal,

6

Elimina e ridisegna tutte le tabelle in un database.

    USE [DatabaseName]
    EXEC sp_msforeachtable "ALTER TABLE ? NOCHECK CONSTRAINT all"       -- Disable All the constraints
    EXEC sp_MSForEachTable "DELETE FROM ?"    -- Delete All the Table data
    Exec sp_MSforeachtable 'DBCC CHECKIDENT(''?'', RESEED, 0)' -- Reseed All the table to 0
    Exec sp_msforeachtable "ALTER TABLE ? WITH CHECK CHECK CONSTRAINT all"  -- Enable All  the constraints back

-- You may ignore the errors that shows the table without Auto increment field.

6

L'avevo capito. Suo:

 DBCC CHECKIDENT ('tablename', RESEED, newseed)

4

Sulla base della risposta accettata, per coloro che hanno riscontrato un problema simile, con qualifica di schema completa:

( [MyDataBase].[MySchemaName].[MyTable]) ... provoca un errore, devi essere nel contesto di quel DB

Cioè, quanto segue genererà un errore:

DBCC CHECKIDENT ([MyDataBase].[MySchemaName].[MyTable], RESEED, 0)

Racchiudere invece il nome completo della tabella con virgolette singole:

DBCC CHECKIDENT ('[MyDataBase].[MySchemaName].[MyTable]', RESEED, 0)

4

Diverse risposte raccomandano di usare una frase simile a questa:

DBCC CHECKIDENT (mytable, RESEED, 0)

Ma l'OP ha detto "cancellato alcuni record", che potrebbero non essere tutti, quindi un valore di 0 non è sempre quello giusto. Un'altra risposta ha suggerito di trovare automaticamente il valore corrente massimo e di eseguire il reseeding su quello, ma ciò si traduce in un problema se non ci sono record nella tabella e quindi max () restituirà NULL. Un commento suggerito usando semplicemente

DBCC CHECKIDENT (mytable)

per reimpostare il valore, ma un altro commento ha affermato correttamente che ciò aumenta il valore al massimo già nella tabella; questo non ridurrà il valore se è già superiore al massimo nella tabella, che è ciò che l'OP voleva fare.

Una soluzione migliore combina queste idee. Il primo CHECKIDENT reimposta il valore su 0 e il secondo reimposta il valore più alto attualmente nella tabella, nel caso in cui vi siano record nella tabella:

DBCC CHECKIDENT (mytable, RESEED, 0)
DBCC CHECKIDENT (mytable)

Come indicato da più commenti, assicurarsi che non vi siano chiavi esterne in altre tabelle che puntano ai record eliminati. Altrimenti quelle chiavi esterne punteranno ai record che crei dopo il reseeding della tabella, che quasi sicuramente non è quello che avevi in ​​mente.


4

Voglio aggiungere questa risposta perché l' DBCC CHECKIDENTapproccio produrrà problemi quando si usano schemi per le tabelle. Usa questo per essere sicuro:

DECLARE @Table AS NVARCHAR(500) = 'myschema.mytable';
DBCC CHECKIDENT (@Table, RESEED, 0);

Se si desidera verificare il successo dell'operazione, utilizzare

SELECT IDENT_CURRENT(@Table);

che dovrebbe produrre 0nell'esempio sopra.


1

Non vuoi farlo in generale. Reseed può creare problemi di integrità dei dati. È davvero solo per l'uso su sistemi di sviluppo in cui si stanno cancellando tutti i dati di test e si ricomincia da capo. Non dovrebbe essere utilizzato su un sistema di produzione nel caso in cui tutti i record correlati non siano stati eliminati (non tutte le tabelle che dovrebbero essere in una relazione di chiave esterna lo sono!). Puoi creare un casino facendo questo e specialmente se intendi farlo regolarmente dopo ogni eliminazione. È una cattiva idea preoccuparsi delle lacune nei valori del campo identità.


6
Non lo userò sempre ed era solo su un db di prova.
jumbojs,

0

Che dire di questo?

ALTER TABLE `table_name`
  MODIFY `id` int(12) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=0;

Questo è un modo rapido e semplice per modificare l'incremento automatico in 0 o in qualsiasi numero desiderato. L'ho capito esportando un database e leggendo il codice da solo.

Puoi anche scriverlo in questo modo per renderlo una soluzione a riga singola:

ALTER TABLE `table_name` MODIFY `id` int(12) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=0;

1
Grazie per questo frammento di codice, che potrebbe fornire un aiuto limitato e immediato. Una spiegazione adeguata migliorerebbe notevolmente il suo valore a lungo termine mostrando perché questa è una buona soluzione al problema e lo renderebbe più utile ai futuri lettori con altre domande simili. Si prega di modificare la risposta di aggiungere qualche spiegazione, tra le ipotesi che hai fatto.
Arrivederci StackExchange
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.