我已经将记录插入到SQL Server数据库表中。该表定义了一个主键,并且自动递增标识种子被设置为“Yes”。这样做主要是因为在SQL Azure中,每个表都必须定义一个主键和标识。

但是由于我必须从表中删除一些记录,这些表的标识种子将受到干扰,索引列(自动生成的增量为1)也将受到干扰。

如何在删除记录后重置标识列,使该列具有升序数字顺序?

标识列在数据库中的任何地方都不能用作外键。


当前回答

删除一个表的所有行,检查表中是否有标识列,将被重新播种。

****警告:所有行将被删除。*****

Create PROCEDURE ClearTableData 
    @TableName varchar(100)
AS
    EXEC ('ALTER TABLE '+@TableName+'  NOCHECK CONSTRAINT ALL ') 
    BEGIN TRY  
        EXEC ('Truncate Table'+@TableName )
        PRINT @TableName +' rows have trancated '
    END TRY  
    BEGIN CATCH  
        EXEC ('Delete From '+@TableName )
        PRINT @TableName +' rows have deleted '
    END CATCH  
    
    IF (OBJECTPROPERTY(OBJECT_ID(@TableName), 'TableHasIdentity'))  = 1 
            DBCC CHECKIDENT (@TableName, RESEED, 0) 

    EXEC ('ALTER TABLE '+@TableName+'  CHECK CONSTRAINT ALL ') 

GO

其他回答

截断表是首选,因为它可以清除记录,重置计数器并回收磁盘空间。

Delete和CheckIdent应该只在外键阻止截断的情况下使用。

对所有表使用这个sp:

补播“youtable”

在删除一条记录后(在触发程序中)

ALTER PROCEDURE [dbo].[RESEED](@Tabla nvarchar(100))

as

-- ********************* CREAR ESTA FUNCIÓN PRIMERO *******************************
/*
create function  dbo.FN_EsIdentidad(@Tabla nvarchar(100), @Campo nvarchar(100))
    returns int
    as
    begin
        return columnproperty ( object_id ( @Tabla  ), @Campo , 'IsIdentity')
    end 
GO
************************************************************************************
*/


declare @CampoIdentidad nvarchar(100)

    SELECT @CampoIdentidad  = Column_Name
        --,dbo.FN_EsIdentidad(Table_Name, Column_name) as EsIdentidad,
        --table_name, column_name 
        FROM information_schema.columns
        where dbo.FN_EsIdentidad(Table_Name, Column_name) = 1 
        and Table_Name=@Tabla


declare @Sql nvarchar(max)
declare @OutPutNum int
set @Sql = 'Select MAX(' + @CampoIdentidad + ') From ' + @Tabla
--select @CampoIdentidad


set @sql = 'Select @ValorOut=max(' + @CampoIdentidad + ') From ' + @Tabla 
declare @ParamDefinition nvarchar(max)
SET @ParamDefinition = '@ValorOut int OUTPUT'

EXECUTE sp_executesql  
    @SQL 
    ,@ParamDefinition  
    ,@ValorOut = @OutPutNum OUTPUT;  

--select @OutPutNum
set @OutPutNum  = coalesce(@OutPutNum ,0)
DBCC CHECKIDENT (@Tabla, RESEED, @OutputNum)

重新播种到0是不太实际的,除非您要清理整个表。

除此之外,安东尼·雷蒙德给出的答案是完美的。首先得到单位列的最大值,然后用max作为种子。

DBCC CHECKIDENT ('TestTable', RESEED, 0)
GO

其中0是标识起始值

虽然大多数答案都建议RESEED到0,但很多时候我们只需要重新播种到下一个可用的Id

declare @max int
select @max=max([Id]) from [TestTable]
if @max IS NULL   --check when max is returned as null
  SET @max = 0
DBCC CHECKIDENT ('[TestTable]', RESEED, @max)

这将检查表并重置到下一个ID。