333

I've deleted some records from a table in a SQL Server database.

The IDs in the table look like this:

99 100 101 1200 1201...

I want to delete the later records (IDs >1200), then I want to reset the auto increment so the next autogenerated ID will be 102. So my records are sequential, Is there a way to do this in SQL Server?

ono2012
  • 4,967
  • 2
  • 33
  • 42
jumbojs
  • 4,768
  • 9
  • 38
  • 50
  • 67
    Please don't say "Don't do it". I hate it when I ask how to do something and all I get is don't. Yes resetting the identity can cause foreign key problems but only if you don't know your database and program accordingly. There are very good reasons for resetting an identity after a sceduled delete - they're called Auditors. Auditors hate to see gaps so fill them, do it in a controlled way and make sure foreign key contraints are maintained. –  Jun 27 '12 at 07:43
  • 7
    @spyder, did you know that you will have gaps if a record insert is rolled back not just for delete? You can't avoid gaps with an autoincrement and it is foolish to try. I've worked for an audit agency and competent auditors can have this explained to them. Further if you have proper audit tables, they can see what happened to those records. Or if there must be no gaps ever for legal reasons (there are a few cases of this), then only an incompetent developer would use an autoincrement and the auditors are rightly upset. – HLGEM Aug 30 '12 at 21:19

14 Answers14

561

Issue the following command to reseed mytable to start at 1:

DBCC CHECKIDENT (mytable, RESEED, 0)

Read about it in the Books on Line (BOL, SQL help). Also be careful that you don't have records higher than the seed you are setting.

Ryan Lundy
  • 204,559
  • 37
  • 180
  • 211
Robert Wagner
  • 17,515
  • 9
  • 56
  • 72
  • 5
    ... because the ids of these records will be happily be reused again, causing a bad mess. – nalply Sep 17 '10 at 10:16
  • 5
    Actually, in order to start IDs at 1, you need to use 0: `DBCC CHECKIDENT (mytable, RESEED, 0)` – Ryan Lundy Dec 24 '12 at 00:33
  • 10
    "DBCC CHECKIDENT ( table_name )" sets the seed to the highest identity in the table, than you don't have to "be careful" – user1027167 Nov 19 '14 at 08:55
  • 4
    @user1027167 No, your answer didn't work for me. It kept incrementing on the highest ID it had internally saved. I had to explicitly use "RESEED, 18" in my case to get "19" as next ID. Without it kept happily incrementing on "29". – Matthis Kohli May 12 '16 at 10:55
  • 1
    [DBCC CHECKIDENT (table_name)](https://msdn.microsoft.com/en-us/library/ms176057.aspx) only change the seed if the identity value is *lower* than the maximum value in the column. So if the identity value already bigger like @MatthisKohli case, the explicit reseed must be called. – Martheen Oct 18 '16 at 03:52
  • DBCC CHECKIDENT -- Schema aware You can surround with single quotes or inside square brackets. Both work. DBCC CHECKIDENT ('Chemical.Products', RESEED, 0) DBCC CHECKIDENT ([Chemical.Products], RESEED, 0) – Asad Naeem Aug 11 '23 at 04:49
116
DBCC CHECKIDENT('databasename.dbo.tablename', RESEED, number)

if number = 0 then in the next insert the auto increment field will contain value 1

if number = 101 then in the next insert the auto increment field will contain value 102


Some additional info... May be useful to you

Before giving auto increment number in above query, you have to make sure your existing table's auto increment column contain values less that number.

To get the maximum value of a column(column_name) from a table(table1), you can use following query

 SELECT MAX(column_name) FROM table1
Fathah Rehman P
  • 8,401
  • 4
  • 40
  • 42
  • Can't you just not include the seed number and it will use the max? For example `DBCC CHECKIDENT('databasename.dbo.tablename')` and do **NOT** include `, RESEED, number`? – Sam Aug 04 '20 at 02:37
50

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

user423430
  • 3,654
  • 3
  • 26
  • 22
  • 1
    "DBCC CHECKIDENT ( table_name )" does the same (possible without race conditions) – user1027167 Nov 19 '14 at 08:57
  • 2
    @user1027167 The docs say 'if the current identity value for a table is less than the maximum identity value stored in the identity column'; that doesn't cover cleanup after data is deleted (re-using id's - often a bad idea). Verified on SQL 2008 – user423430 Dec 05 '14 at 19:37
  • 1
    The best systematic and automatic answer. Bravo! – Mehdi Khademloo Oct 13 '15 at 13:08
32

If you're using MySQL, try this:

ALTER TABLE tablename AUTO_INCREMENT = 1
shaahiin
  • 1,243
  • 1
  • 16
  • 26
xaa
  • 818
  • 13
  • 13
10

I figured it out. It's:

 DBCC CHECKIDENT ('tablename', RESEED, newseed)
shA.t
  • 16,580
  • 5
  • 54
  • 111
jumbojs
  • 4,768
  • 9
  • 38
  • 50
  • and how do you get "newseed"? Not that I don't know, only that a complete answer would explain this. – iGanja Dec 21 '21 at 22:35
7

Delete and Reseed all the tables in a 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.
BMG
  • 489
  • 6
  • 9
6

Based on the accepted answer, for those who encountered a similar issue, with full schema qualification:

([MyDataBase].[MySchemaName].[MyTable])... results in an error, you need to be in the context of that DB

That is, the following will throw an error:

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

Enclose the fully-qualified table name with single quotes instead:

DBCC CHECKIDENT ('[MyDataBase].[MySchemaName].[MyTable]', RESEED, 0)
tinonetic
  • 7,751
  • 11
  • 54
  • 79
6

Several answers recommend using a statement something like this:

DBCC CHECKIDENT (mytable, RESEED, 0)

But the OP said "deleted some records", which may not be all of them, so a value of 0 is not always the right one. Another answer suggested automatically finding the maximum current value and reseeding to that one, but that runs into trouble if there are no records in the table, and thus max() will return NULL. A comment suggested using simply

DBCC CHECKIDENT (mytable)

to reset the value, but another comment correctly stated that this only increases the value to the maximum already in the table; this will not reduce the value if it is already higher than the maximum in the table, which is what the OP wanted to do.

A better solution combines these ideas. The first CHECKIDENT resets the value to 0, and the second resets it to the highest value currently in the table, in case there are records in the table:

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

As multiple comments have indicated, make sure there are no foreign keys in other tables pointing to the deleted records. Otherwise those foreign keys will point at records you create after reseeding the table, which is almost certainly not what you had in mind.

Michael Rodby
  • 336
  • 4
  • 6
  • Second command needs to be DBCC CHECKIDENT (mytable, RESEED) – statler Oct 30 '21 at 21:59
  • @statler according to https://learn.microsoft.com/en-us/sql/t-sql/database-console-commands/dbcc-checkident-transact-sql?view=sql-server-ver15 the commands "DBCC CHECKIDENT (table_name)" and "DBCC CHECKIDENT (table_name, RESEED)" do the same thing. See the second entry in the Remarks section. – Michael Rodby Nov 01 '21 at 04:25
  • Apparently, but unfortunately, if you run the command without the RESEED on an db, it doesn't work. Cannot explaing the documentation. Just is. - at least on the databases I was using. – statler Nov 02 '21 at 06:57
4

I want to add this answer because the DBCC CHECKIDENT-approach will product problems when you use schemas for tables. Use this to be sure:

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

If you want to check the success of the operation, use

SELECT IDENT_CURRENT(@Table);

which should output 0 in the example above.

Alexander Schmidt
  • 5,631
  • 4
  • 39
  • 79
1

You do not want to do this in general. Reseed can create data integrity problems. It is really only for use on development systems where you are wiping out all test data and starting over. It should not be used on a production system in case all related records have not been deleted (not every table that should be in a foreign key relationship is!). You can create a mess doing this and especially if you mean to do it on a regular basis after every delete. It is a bad idea to worry about gaps in you identity field values.

HLGEM
  • 94,695
  • 15
  • 113
  • 186
1

What about this?

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

This is a quick and simple way to change the auto increment to 0 or whatever number you want. I figured this out by exporting a database and reading the code myself.

You can also write it like this to make it a single-line solution:

ALTER TABLE `table_name` MODIFY `id` int(12) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=0;
  • 1
    Thank you for this code snippet, which might provide some limited, immediate help. A [proper explanation would greatly improve its long-term value](//meta.stackexchange.com/q/114762/206345) by showing _why_ this is a good solution to the problem, and would make it more useful to future readers with other, similar questions. Please [edit] your answer to add some explanation, including the assumptions you've made. – Blue Mar 05 '19 at 00:41
1

To reset every key in the database to autoincrement from the max of the last highest key:

Exec sp_MSforeachtable 'DBCC CHECKIDENT(''?'', RESEED, 0)'

Exec sp_MSforeachtable 'DBCC CHECKIDENT(''?'', RESEED)'
statler
  • 1,322
  • 2
  • 15
  • 24
  • This is a slick way to call a DBCC command on all tables. Unfortunately, without specifying a reseed value, the CHECKINDENT command does nothing for me but identify the max value. @user423430 still presents the only answer that recovers lost identity values for me. It would be great if I could exec that entire set of commands. I've tried, but the stored proc does not seem to accept multiple commands. – iGanja Dec 21 '21 at 22:51
0

If you just want to reset the primary key/sequence to start with a sequence you want in a SQL server, here's the solution -

IDs:

99 100 101 1200 1201...

  1. Drop rows with IDs >= 1200. (Be careful if you have foreign key constraints tied to these which has to be dealed with or deleted too to be able to delete this.)
  2. Now you want to make sure you know the MAX ID to be sure:

declare @max_id as int = (SELECT MAX(your_column_name) FROM your_table)+1;

(Note: +1 to start the ID sequence after max value)

  1. Restart your sequence:

exec('alter sequence your_column_name restart with ' + @max_id);

(Note: Space after with is necessary) Now new records will start with 102 as the ID.

0

I know this is an old question. However, I was looking for a similar solution for MySQL and this question showed up.

for those who are looking for MySQL solution, you need to run this query:

// important!!! You cannot reset the counter to a value less than or equal to the value that is currently in use. For both InnoDB and MyISAM, if the value is less than or equal to the maximum value currently in the AUTO_INCREMENT column, the value is reset to the current maximum AUTO_INCREMENT column value plus one.
   
ALTER TABLE <your-table-name> AUTO_INCREMENT = 100

documentation

Joseph Ali
  • 345
  • 1
  • 5
  • 11