While working on a project, I needed to change the identity column for a certain set of tables to be negative while keeping the current positive values that it already had. I found a quick and easy way to do it using the following:
DBCC CHECKIDENT('your_table', RESEED, new_identity_value)
There were however a few drawbacks to this:
1) You cannot set the identity increment along with it. This means if you change it to negative, you cannot start at 0 or -1 if your increment is positive. Your only real solution is to put it at a huge negative number such as -1 billion or -2^31 and have it count forward.
2) If you happen to change the identity seed to a number (say 10) but a number like 15 already exists, assuming the increment is 1, it will eventually reach 15 and sql server will throw an error
3) If you ever insert into the table by turning identity insert on you may run into issues. Say you changed the seed to be a negative value, but you are inserting id of 50 forcefully - your new identity seed is now 50, it is no longer the negative number.
4) If you perform a truncate table,it will reset it to the identiy seed defined when the table was created.
Without going into too much detail, the project I was working on involved a sql server database that sometimes gets populated directly (via an application) and other times gets populated by another sql server. Records generated by the application are given a negative number so it does not conflict with records generated by the other server. (There was not a way to use sql replication for many reasons, so this was the best solution at the time).
Because the sql command above had the listed problems, we decided to set the identity columns to -2^31. Since the increment is 1 and we can't changed it (problem #1), it'll take a while before we reach 0. Unfortunately because we will occasionally be receiving records from another server, everytime it does an identity insert with a positive number, it's going to reset what we've done (problem #3)
The other problem is if we reset the identity BACK to -2^31, we will run into problem #2. The only solution I could think of to solve this was to do the following:
After the server does its inserts, we need to set it to the minimum negative possible that won't cause a conflict (e.g. if our last negative number used was -1 billion, we need to set it to -1 billion so that the next id created will be -999,999,999)
We can select the identity column by using the IDENTITYCOL keyword. We can use min/max functions to get us the min or max identity. The only problem is we not only want the minimum identity, but we want the min usable identity that won't conflict. See solution below:
DECLARE @TEMP int
SELECT @TEMP =
(CASE when max(IDENTITYCOL ) < 0 THEN max(identitycol) ELSE -2147483647 END)
FROM my_table where IDENTITYCOL < 0
We now use the value of @TEMP to re-assign the identity column
DBCC CHECKIDENT('my_table', RESEED, @TEMP )
Now we just need to be sure to run this everytime we need to reset the identity back to a negative number.
I don't know if this is the only solution, but it was all I could do at the time because I could not find a way to dynamically change the identity seed value for multiple tables. I'm curious if there's another way!