2009-02-04 7 views
199

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

+33

Per favore non dire "Non farlo". Odio quando chiedo come fare qualcosa e tutto quello che ottengo è no. Sì, la reimpostazione dell'identità può causare problemi con le chiavi esterne, ma solo se non si conosce il database e il programma di conseguenza. Ci sono ottime ragioni per reimpostare un'identità dopo un'eliminazione scansita: si chiamano revisori. Gli auditor odiano vedere lacune in modo da riempirle, farlo in modo controllato e assicurarsi che i contorni delle chiavi straniere siano mantenuti. –

+6

@spyder, lo sapevi che avresti degli spazi vuoti se un inserto del record venisse ripristinato non solo per l'eliminazione? Non puoi evitare le lacune con un autoincremento ed è sciocco da provare. Ho lavorato per un'agenzia di audit e gli auditor competenti possono averlo spiegato a loro. Inoltre, se hai tabelle di controllo corrette, possono vedere cosa è successo a quei record. O se non ci sono mai lacune per ragioni legali (ci sono alcuni casi di questo), solo uno sviluppatore incompetente userebbe un autoincremento e gli auditor sono giustamente turbati. – HLGEM

risposta

348

il seguente comando per reseed MyTable per iniziare a 1:

DBCC CHECKIDENT (mytable, RESEED, 0) 

Leggi su di esso nei libri sulla linea (BOL, SQL aiuto). Fai anche attenzione a non avere record più alti del seme che stai impostando.

+3

... perché gli ID di questi record saranno felicemente riutilizzati, causando un brutto guaio. – nalply

+0

che ne dici di uno zero? – Joset

+3

In realtà, per avviare gli ID a 1, è necessario utilizzare 0: 'DBCC CHECKIDENT (mytable, RESEED, 0)' –

3

L'ho capito. È:

DBCC CHECKIDENT ('tablename', RESEED, newseed) 
2

Non si vuole fare questo 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 ricominciare da capo. Non dovrebbe essere usato su un sistema di produzione nel caso in cui tutti i record relativi non siano stati cancellati (non tutte le tabelle che dovrebbero essere in una relazione di chiave esterna sono!). È possibile creare un pasticcio facendo questo e soprattutto se si intende farlo regolarmente dopo ogni eliminazione. È una cattiva idea preoccuparsi delle lacune nei valori dei campi di identità.

+6

Non lo userò sempre ed è stato solo su un db di prova. – jumbojs

29

semi idiot-proof:

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à"; questo non copre la pulizia dopo che i dati sono stati cancellati (riutilizzando id - spesso una cattiva idea). Verificato su SQL 2008 – user423430

+1

La migliore risposta sistematica e automatica. Bravo! –

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

se number = 0 allora nel prossimo inserto campo incremento automatico conterrà il valore 1

se number = 101 poi nel prossimo inserimento il campo di incremento automatico conterrà il valore 102


Alcune informazioni aggiuntive ... Può essere utile a voi

Prima di dare incremento automatico number al precedente query, è necessario assicurarsi colonna di incremento automatico della vostra tabella esistente contiene i valori inferiori che number.

per ottenere il valore massimo di una colonna (column_name) da una tabella (tabella 1), è possibile utilizzare seguente query

SELECT MAX(column_name) FROM table1 
7

Prova questo:

ALTER TABLE tablename AUTO_INCREMENT = 1 
+4

Se non sbaglio, la risposta è buona per mysql. – Carol

+1

Questa è una risposta per MySQL. OP sta chiedendo di MSSQL. – reformed

5

Elimina e reseed tutti i tavoli 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. 
4

Sulla base della risposta accettata, per coloro che ha incontrato un problema simile, con la qualificazione piena schema:

([MyDataBase].[MySchemaName].[MyTable]) ...si traduce in un errore, è necessario essere nel contesto di tale DB

Cioè, il seguente genera un errore:

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

Racchiudere il nome di tabella pienamente qualificato con apici invece:

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

più risposte consiglia di utilizzare un qualcosa di dichiarazione come questa:

DBCC CHECKIDENT (mytable, RESEED, 0) 

Ma l'OP diceva "cancellati alcuni record", che potrebbero non essere tutti, quindi un valore di 0 non è sempre quello giusto. Un'altra risposta suggeriva di trovare automaticamente il valore corrente massimo e di ricomporre quello, ma questo si guasta se non ci sono record nella tabella, e quindi max() restituirà NULL. Un commento ha suggerito di utilizzare semplicemente

DBCC CHECKIDENT (mytable) 

per azzerare il valore, ma un altro commento ha affermato giustamente che questo aumenta solo 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 a 0, e il secondo si resetta con il valore più alto attualmente in tabella, nel caso in cui non ci sono record nella tabella:

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

Come più commenti hanno indicato, assicurarsi che non ci sono chiavi esterne in altre tabelle che puntano ai record cancellati. Altrimenti, quelle chiavi esterne indicheranno i record che creerai dopo aver riesaminato la tabella, il che non è quasi certamente quello che avevi in ​​mente.

0

Desidero aggiungere questa risposta perché lo script DBCC CHECKIDENT si guasta quando si utilizzano gli schemi per le tabelle. Usare questo per essere sicuri:

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

Se si desidera controllare il successo dell'operazione, utilizzare

SELECT IDENT_CURRENT(@Table); 

che dovrebbe uscita 0 nell'esempio di cui sopra.