SQL server identity column values start at 0 instead of 1

Viewed 77066

I've got a strange situation with some tables in my database starting its IDs from 0, even though TABLE CREATE has IDENTITY(1,1). This is so for some tables, but not for others. It has worked until today.

I've tried resetting identity column:

DBCC CHECKIDENT (SyncSession, reseed, 0);

But new records start with 0. I have tried doing this for all tables, but some still start from 0 and some from 1.

Any pointers?

(i'm using SQL Server Express 2005 with Advanced Services)

7 Answers

From DBCC CHECKIDENT

DBCC CHECKIDENT ( table_name, RESEED, new_reseed_value )

If no rows have been inserted to the table since it was created, or all rows have been removed by using the TRUNCATE TABLE statement, the first row inserted after you run DBCC CHECKIDENT uses new_reseed_value as the identity. Otherwise, the next row inserted uses new_reseed_value + the current increment value.

So, this is expected for an empty or truncated table.

This is logical, since you've changed (reseeded) the identity value to zero ?

DBCC CHECKIDENT (SyncSession, reseed, 1)

will reseed your identity column, and make sure that the first new record will start with 1.

The currently accepted answer only explains this annoying phenomenon. Only one answer offers some sort of a solution, but not really practical because it requires a dummy insertion, which makes it hard to generalize.

The only generic solution is to reseed the identity value, then check the current identity value and reseed it again when it's 0. This can be done by a stored procedure:

CREATE OR ALTER PROCEDURE ReseedIdentity
    @tableName SYSNAME
AS
BEGIN
    DBCC CHECKIDENT(@tableName, RESEED, 0)
    IF IDENT_CURRENT(@tableName) = 0
    BEGIN
        DBCC CHECKIDENT(@tableName, RESEED, 1)
    END
END

This will always start new records at identity value 1, whether it's a new table, after truncating or after deleting all records.

If there are identity specifications starting at higher seed values a somewhat more advanced version can be used, which is a generalization of the former:

CREATE OR ALTER PROCEDURE ReseedIdentity
    @tableName SYSNAME
AS
BEGIN
    DECLARE @seed NUMERIC(18,0) = IDENT_SEED(@tableName) - 1;
    DBCC CHECKIDENT(@tableName, RESEED, @seed)
    IF IDENT_CURRENT(@tableName) = @seed
    BEGIN
        SET @seed = @seed + 1
        DBCC CHECKIDENT(@tableName, RESEED, @seed)
    END
END
Related