Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

DBCC CHECKIDENT RESEED -- is new value required?

All the documentation I read about reseeding suggests something along the lines of:

  1. SET @maxIdentityValue = (SELECT MAX(id) FROM tablename)
  2. run DBCC CHECKIDENT('tablename', RESEED, @maxIdentityValue)

And yet it appears to me that a simple DBCC CHECKIDENT('tablename', RESEED) is all that's needed, and it will automatically determine the correct identity value from the table without supplying a max value.

Is there a reason (performance or otherwise) that extracting the value using MAX first is preferred?

Piggyback question: the reason I need to reseed is because I'm using replication and identities keep getting set to Null each time the database replication runs. What am I doing wrong? How can I maintain the correct identity seed for each table?

Update (Current solution)

For now I'm not using the max value. This is the stored procedure I'm using (I generate it using a query on sys.columns and then just cutting and pasting each into a new query window. Messier, slower, less elegant, but I'm not very familiar with stored procedures and don't want to use dynamic SQL queries):

declare @seedval integer
declare @maxval integer
declare @newval integer
set @seedval = (select ident_current('mytable'));
set @maxval = (select MAX(id) from mytable);
if @maxval > @seedval or @seedval is NULL
BEGIN
    print 'Need to reseed: max is '  + cast(@maxval as varchar) + ' and seed is ' + cast(@seedval as varchar) 
    dbcc checkident('mytable', RESEED);
    set @newval = (select ident_current('mytable'));
    print 'Max is ' + cast(@maxval as varchar) + ' and seed is ' + cast(@newval as varchar) 
END 
ELSE
    print 'No need to reseed'; 
like image 803
Jordan Reiter Avatar asked Jan 21 '13 18:01

Jordan Reiter


People also ask

What is DBCC Checkident reseed?

DBCC CHECKIDENT returns the current identity value and the current maximum value of the identity column. If the two values are not the same, you should reset the identity value to avoid potential errors or gaps in the sequence of values. DBCC CHECKIDENT ( table_name )

How do I reseed identity value in SQL Server?

Reset the Identity Value Using the DBCC CHECKIDENT Method : Here, to reset the Identity column in SQL Server you can use DBCC CHECKIDENT method. Syntax : DBCC CHECKIDENT ('table_name', RESEED, new_value); Note : If we reset the existing records in the table and insert new records, then it will show an error.

Does identity insert reseed?

Automatic reseeding can occur This happens when you turn on IDENTITY_INSERT for the table, then insert a row with an ID that is higher than the current ID. The IDENTITY seed value will be reset to that higher ID value you outlined.

What is seed value in SQL?

The seed is the value of the first row loaded into the table. The increment is the incremental value added to the identity value of the previous row.


3 Answers

As it is stated in MSDN, it is fairly enough to use just:

 DBCC CHECKIDENT('tablename', RESEED)  

most of the time, however there are these two conditions where it will not work:

  • The current identity value is larger than the maximum value in the table.
  • All rows are deleted from the table.

in which you have to go with they way that you mentioned (select max(id) and the rest), so why bother in the first place? :)

like image 123
mohas Avatar answered Oct 24 '22 10:10

mohas


There are cases where you might want to determine the max so that you can reseed and leave a gap (e.g. max + 100). One case might be when you have multiple copies of a table and you are going to distribute independent but mutually exclusive identity ranges from them.

But still, I'm not confident that the RESEED without a parameter will work correctly in all scenarios.

Is it a common occurrence that you're reseeding tables back to the max? Why? Poorly coded application that generates a bunch of rows in a loop that you end up rolling back?

In any case, you'll want to wrap the MAX and RESEED in a transaction to prevent the chance that a user will insert a new row after you've taken the max but before you've issued the reseed.

like image 2
Aaron Bertrand Avatar answered Oct 24 '22 10:10

Aaron Bertrand


(I'm reposting my answer from this other SO page)

Perhaps the easiest way (as crazy as this sounds and as code-smelly as it looks) is to just run DBCC CHECKIDENT twice like this:

-- sets all the seeds to 1
exec sp_MSforeachtable @command1 = 'DBCC CHECKIDENT (''?'', RESEED, 1)'

-- run it again to get MSSQL to figure out the MAX/NEXT seed automatically
exec sp_MSforeachtable @command1 = 'DBCC CHECKIDENT (''?'')'

Done.

If you want, you can run it once more to see what all the seeds were set to:

-- run it again to display what the seeds are now set to
exec sp_MSforeachtable @command1 = 'DBCC CHECKIDENT (''?'')'

This is just a creative way to take advantage of the comment from the documentation:

If the current identity value for a table is less than the maximum identity value stored in the identity column, it is reset using the maximum value in the identity column.

like image 2
101010 Avatar answered Oct 24 '22 11:10

101010