CHECKIDENT DBCC sets identifier 0

I use this code to reset the id in the table:

DBCC CHECKIDENT('TableName', RESEED, 0) 

This works fine in most cases, with the first insertion that I insert 1 into the identifier column. However, if I delete db and recreate it (using written scripts) and then call DBCC CHECKIDENT, the first element inserted will have identifier 0.

Any ideas?

EDIT: After research, it turned out that I did not read the documentation properly: http://msdn.microsoft.com/en-us/library/aa258817(SQL.80).aspx - "The current identifier value is set to new_reseed_value. If neither one row has not been inserted into the table since it was created, the first row inserted after DBCC CHECKIDENT will use new_reseed_value as an identifier. Otherwise, the next inserted row will use new_reseed_value + 1. "

+66
sql sql-server
Jan 23 '09 at 11:17
source share
9 answers

As you pointed out in your question, this is documented behavior . It still seems strange to me. I use to refill the test database, and although I do not rely on the values ​​of the identification fields, it was a little annoying to have different values ​​when I first populated the database from scratch and after deleting all the data and refilling.

A possible solution is to use truncate to clear the table instead of deleting it. But then you need to drop all restrictions and then recreate them

Thus, it always behaves like a newly created table, and there is no need to call DBCC CHECKIDENT. The first identifier value will be indicated in the table definition, and it will be the same regardless of whether you insert data for the first time or for the Nth

+22
Jan 23 '09 at 13:15
source share

You are correct in what you write when editing your question.

After starting DBCC CHECKIDENT('TableName', RESEED, 0) :
- Newly created tables will start with identifier 0
- Existing tables will continue with identifier 1

The solution is in the script below, this is kind of poor mans-truncate :)

 -- Remove all records from the Table DELETE FROM TableName -- Use sys.identity_columns to see if there was a last known identity value -- for the Table. If there was one, the Table is not new and needs a reset IF EXISTS (SELECT * FROM sys.identity_columns WHERE OBJECT_NAME(OBJECT_ID) = 'TableName' AND last_value IS NOT NULL) DBCC CHECKIDENT (TableName, RESEED, 0); 
+57
Nov 09 '12 at 6:50
source share

Change the statement to

  DBCC CHECKIDENT('TableName', RESEED, 1) 

This will start at 2 (or 1 when you recreate the table), but it will never be 0.

+4
Jan 23 '09 at 11:32
source share

I did this as an experiment with resetting the value to 0, since I want my first identity column to be 0 and it works.

 dbcc CHECKIDENT(MOVIE,RESEED,0) dbcc CHECKIDENT(MOVIE,RESEED,-1) DBCC CHECKIDENT(MOVIE,NORESEED) 
+3
Nov 08 '13 at 17:21
source share

It seems ridiculous that you cannot set / reset the identifier column with a single command to cover both cases if records were inserted into the table. I could not understand the behavior that I experienced until I came across this question on SO!

My solution (ugly, but works) is to explicitly check the sys.identity_columns.last_value table (which tells you if records are inserted in the table) and call the appropriate DBCC CHECKIDENT in each case. It looks like this:

 DECLARE @last_value INT = CONVERT(INT, (SELECT last_value FROM sys.identity_columns WHERE OBJECT_NAME(OBJECT_ID) = 'MyTable')); IF @last_value IS NULL BEGIN -- Table newly created and no rows inserted yet; start the IDs off from 1 DBCC CHECKIDENT ('MyTable', RESEED, 1); END ELSE BEGIN -- Table has rows; ensure the IDs continue from the last ID used DECLARE @lastValUsed INT = (SELECT ISNULL(MAX(ID),0) FROM MyTable); DBCC CHECKIDENT ('MyTable', RESEED, @lastValUsed); END 
+2
Sep 13 '17 at 15:48
source share

See also here: http://sqlblog.com/blogs/alexander_kuznetsov/archive/2008/06/26/fun-with-dbcc-chekident.aspx

This is the documented behavior why you run CHECKIDENT if you recreate the table, in this case skip the step or use TRUNCATE (if you don't have FK relationships)

+1
Jan 23 '09 at 14:19
source share

I used this in SQL to set IDENTITY for a specific value: -

 DECLARE @ID int = 42; DECLARE @TABLENAME varchar(50) = 'tablename' DECLARE @SQL nvarchar(1000) = 'IF EXISTS (SELECT * FROM sys.identity_columns WHERE OBJECT_NAME(OBJECT_ID) = '''+@TABLENAME+''' AND last_value IS NOT NULL) BEGIN DBCC CHECKIDENT('+@TABLENAME+', RESEED,' + CONVERT(VARCHAR(10),@ID-1)+'); END ELSE BEGIN DBCC CHECKIDENT('+@TABLENAME+', RESEED,' + CONVERT(VARCHAR(10),@ID)+'); END'; EXEC (@SQL); 

And this is in C # to set a specific value: -

 SetIdentity(context, "tablename", 42); . . private static void SetIdentity(DbContext context, string table,int id) { string str = "IF EXISTS (SELECT * FROM sys.identity_columns WHERE OBJECT_NAME(OBJECT_ID) = '" + table + "' AND last_value IS NOT NULL)\nBEGIN\n"; str += "DBCC CHECKIDENT('" + table + "', RESEED," + (id - 1).ToString() + ");\n"; str += "END\nELSE\nBEGIN\n"; str += "DBCC CHECKIDENT('" + table + "', RESEED," + (id).ToString() + ");\n"; str += "END\n"; context.Database.ExecuteSqlCommand(str); } 

This is based on the answers above and always ensures that the next value is 42 (in this case).

+1
Apr 11 '17 at 13:11
source share

Just do it:

 IF EXISTS (SELECT * FROM tablename) BEGIN DELETE from tablename DBCC checkident ('tablename', reseed, 0) END 
0
Jun 04 '19 at 13:53 on
source share
 USE AdventureWorks2012; GO DBCC CHECKIDENT ('Person.AddressType', RESEED, 0); GO AdventureWorks2012=Your databasename Person.AddressType=Your tablename 
-one
Nov 25 '16 at 7:12
source share



All Articles