删除后在SQL Server中重置自动增量


265

我已经从SQL Server数据库的表中删除了一些记录。现在,ID从101变为1200。我想再次删除记录,但是我希望ID返回至102。在SQL Server中有没有办法做到这一点?


46
请不要说“不要做”。当我问如何做某事时,我讨厌它,而我所得到的却不是。是的,重置身份会导致外键问题,但前提是您不知道数据库和相应程序。在有计划的删除后有充分的理由重置身份-他们被称为审核员。审核员不愿看到这样的空白,以可控的方式进行填充,并确保保留外键约束。

6
@spyder,您是否知道如果回滚一条记录插入而不仅仅是删除一条记录,就会有空白吗?您无法避免自动递增的差距,尝试这样做是愚蠢的。我曾在一家审计机构工作,有能力的审计师可以向他们解释这一点。此外,如果您有适当的审核表,他们可以查看这些记录所发生的情况。或者,如果出于法律原因(在某些情况下)绝不存在差距,那么只有不称职的开发人员会使用自动递增功能,而审计师会感到不安。
HLGEM

Answers:


454

发出以下命令重新设置mytable的种子,使其从1开始:

DBCC CHECKIDENT (mytable, RESEED, 0)

在联机丛书(BOL,SQL帮助)中阅读有关它的信息。另外请注意,您所记录的种子数不要超过您设置的种子数。


4
...,因为这些记录的ID将很高兴再次被重用,从而导致混乱。
2010年

3
实际上,要以1开头ID,您需要使用0: DBCC CHECKIDENT (mytable, RESEED, 0)
Ryan Lundy 2012年

7
“ DBCC CHECKIDENT(table_name)”将种子设置为表中的最高标识,这样您就不必“小心”了
user1027167 2014年

4
@ user1027167不,您的答案对我不起作用。它不断增加内部保存的最高ID。在本例中,我必须明确使用“ RESEED,18”来获取“ 19”作为下一个ID。没有它,快乐地增加到“ 29”。
Matthis Kohli

仅当标识值低于列中的最大值时,DBCC CHECKIDENT(table_name)才更改种子。因此,如果标识值已经像@MatthisKohli的情况一样大,则必须调用显式种子。
Martheen '16

82
DBCC CHECKIDENT('databasename.dbo.tablename', RESEED, number)

如果number = 0,则在下一次插入时,自动递增字段将包含值1

如果number = 101,则在下一次插入时,自动递增字段将包含值102


一些其他信息...可能对您有用。在上述查询中

提供自动增量之前number,您必须确保现有表的自动增量列包含的值小于number

要从表(table1)获取列(column_name)的最大值,可以使用以下查询

 SELECT MAX(column_name) FROM table1

37

半防白痴:

declare @max int;  
select @max = max(key) from table;  
dbcc checkident(table,reseed,@max)

http://sqlserverplanet.com/tsql/using-dbcc-checkident-to-reseed-a-table-after-delete


1
“ DBCC CHECKIDENT(table_name)”执行相同的操作(可能在没有竞争条件的情况下)
user1027167 2014年

2
@ user1027167文档说“如果表的当前标识值小于存储在标识列中的最大标识值”;删除数据后不包括清除操作(重新使用id -通常是个坏主意)。经过SQL 2008验证
user423430 2014年

1
最佳的系统和自动答案。太棒了!
Mehdi Khademloo 2015年

11

如果您使用的是MySQL,请尝试以下操作:

ALTER TABLE tablename AUTO_INCREMENT = 1

3
这是MySQL的答案。OP正在询问有关MSSQL的问题。
改革

问题是关于MS SQL Server的
Saher Ahwal '18

6

删除并重新设置数据库中的所有表。

    USE [DatabaseName]
    EXEC sp_msforeachtable "ALTER TABLE ? NOCHECK CONSTRAINT all"       -- Disable All the constraints
    EXEC sp_MSForEachTable "DELETE FROM ?"    -- Delete All the Table data
    Exec sp_MSforeachtable 'DBCC CHECKIDENT(''?'', RESEED, 0)' -- Reseed All the table to 0
    Exec sp_msforeachtable "ALTER TABLE ? WITH CHECK CHECK CONSTRAINT all"  -- Enable All  the constraints back

-- You may ignore the errors that shows the table without Auto increment field.

6

我想到了。它的:

 DBCC CHECKIDENT ('tablename', RESEED, newseed)

4

根据公认的答案,对于遇到相似问题且具有完整模式资格的人员:

[MyDataBase].[MySchemaName].[MyTable])...导致错误,您需要在该数据库的上下文中

也就是说,以下将引发错误:

DBCC CHECKIDENT ([MyDataBase].[MySchemaName].[MyTable], RESEED, 0)

请将全限定表名用单引号引起来:

DBCC CHECKIDENT ('[MyDataBase].[MySchemaName].[MyTable]', RESEED, 0)

4

有几个答案建议使用类似以下的语句:

DBCC CHECKIDENT (mytable, RESEED, 0)

但是OP表示“删除了一些记录”,可能不是全部,因此0值并不总是正确的。另一个答案建议自动找到最大电流值并重新补乘该最大值,但是如果表中没有记录,则会遇到麻烦,因此max()将返回NULL。建议使用简单的评论

DBCC CHECKIDENT (mytable)

重置该值,但是另一条正确的注释指出,这只会将该值增加到表中已经存在的最大值;如果该值已经大于表中的最大值(OP希望这样做),则不会减小该值。

更好的解决方案结合了这些想法。如果表中有记录,则第一个CHECKIDENT将该值重置为0,第二个CHECKIDENT将其重置为当前表中的最大值:

DBCC CHECKIDENT (mytable, RESEED, 0)
DBCC CHECKIDENT (mytable)

如多个注释所示,请确保其他表中没有指向已删除记录的外键。否则,这些外键将指向您在重新创建表后创建的记录,这几乎可以肯定不是您要记住的。


4

我想添加此答案,因为DBCC CHECKIDENT-approach在为表使用架构时会产生问题。使用此来确保:

DECLARE @Table AS NVARCHAR(500) = 'myschema.mytable';
DBCC CHECKIDENT (@Table, RESEED, 0);

如果要检查操作是否成功,请使用

SELECT IDENT_CURRENT(@Table);

应该0在上面的示例中输出。


1

您通常不想这样做。种子会产生数据完整性问题。它实际上仅适用于要删除所有测试数据并重新开始的开发系统。万一所有相关记录都未被删除(不是每个应该具有外键关系的表都被删除!),则不应在生产系统上使用它。您可以创建一个混乱的地方,尤其是如果您打算在每次删除后定期这样做的话。担心身份字段值之间的差距是个坏主意。


6
我不会一直使用它,它只是在测试数据库上。
jumbojs

0

那这个呢?

ALTER TABLE `table_name`
  MODIFY `id` int(12) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=0;

这是一种将自动增量更改为0或所需数字的快速简便的方法。我通过导出数据库并自己阅读代码来解决了这一问题。

您也可以这样编写,使其成为单行解决方案:

ALTER TABLE `table_name` MODIFY `id` int(12) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=0;

1
感谢您提供此代码段,它可能会提供一些有限的即时帮助。一个适当的解释,将大大提高其长期的价值通过展示为什么这是一个很好的解决了这个问题,并会使其与其他类似的问题,更有助于未来的读者。请编辑您的答案以添加一些解释,包括您所做的假设。
再见StackExchange
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.