I\'m using this code to reset the identity on a table:
DBCC CHECKIDENT(\'TableName\', RESEED, 0)
This works fine most of the time, with the f
You are right in what you write in the edit of your question.
After running DBCC CHECKIDENT('TableName', RESEED, 0)
:
- Newly created tables will start with identity 0
- Existing tables will continue with identity 1
The solution is in the script below, it's sort of a 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);
I have used this in SQL to set IDENTITY to a particular 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 in C# to set a particular 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 builds on the above answers and always makes sure the next value is 42 (in this case).
As you pointed out in your question it is a documented behavior. I still find it strange though. I use to repopulate the test database and even though I do not rely on the values of identity fields it was a bit of annoying to have different values when populating the database for the first time from scratch and after removing all data and populating again.
A possible solution is to use truncate to clean the table instead of delete. But then you need to drop all the constraints and recreate them afterwards
In that way it always behaves as a newly created table and there is no need to call DBCC CHECKIDENT. The first identity value will be the one specified in the table definition and it will be the same no matter if you insert the data for the first time or for the N-th
Simply do this:
IF EXISTS (SELECT * FROM tablename)
BEGIN
DELETE from tablename
DBCC checkident ('tablename', reseed, 0)
END
I did this as an experiment to reset the value to 0 as I want my first identity column to be 0 and it's working.
dbcc CHECKIDENT(MOVIE,RESEED,0)
dbcc CHECKIDENT(MOVIE,RESEED,-1)
DBCC CHECKIDENT(MOVIE,NORESEED)
See also here: http://sqlblog.com/blogs/alexander_kuznetsov/archive/2008/06/26/fun-with-dbcc-chekident.aspx
This is documented behavior, why do you run CHECKIDENT if you recreate the table, in that case skip the step or use TRUNCATE (if you don't have FK relationships)