删除SQL Server中的记录后重置身份种子
我已经将记录插入到SQL Server数据库表中。 该表有一个主键定义和自动增量身份种子设置为“是”。 这主要是因为在SQL Azure中,每个表都必须定义主键和标识。
但由于我必须从表中删除一些记录,因此这些表的标识种子将受到干扰,并且索引列(自动生成的增量为1)将受到干扰。
在删除记录后,如何重置标识列,以便列的序号按照升序排列?
数据库中的任何地方都不使用标识列作为外键。
DBCC CHECKIDENT
管理命令用于重置身份计数器。 命令语法是:
DBCC CHECKIDENT (table_name [, { NORESEED | { RESEED [, new_reseed_value ]}}])
[ WITH NO_INFOMSGS ]
例:
DBCC CHECKIDENT ('[TestTable]', RESEED, 0);
GO
它在以前版本的Azure SQL数据库中不受支持,但现在受支持。
请注意,根据文档, new_reseed_value
参数在SQL Server版本中有所不同:
如果表中存在行,则使用new_reseed_value值插入下一行。 在版本SQL Server 2008 R2及更早版本中,插入的下一行使用new_reseed_value +当前增量值。
但是, 我发现这些信息具有误导性 (实际上只是错误),因为观察到的行为表明至少SQL Server 2012仍使用new_reseed_value +当前增量值逻辑。 微软甚至与其在同一页上找到的自己的Example C
相矛盾:
C.迫使当前身份值达到新值
下面的示例强制AddressType表中AddressTypeID列中的当前标识值为10.因为该表具有现有行,所插入的下一行将使用11作为该值,也就是定义的新当前增量值列值加1。
USE AdventureWorks2012;
GO
DBCC CHECKIDENT ('Person.AddressType', RESEED, 10);
GO
尽管如此,这些都为更新的SQL Server版本留下了不同行为的选项。 我想唯一可以肯定的方式是,直到微软在自己的文档中清除了一些东西,就是在使用之前进行实际测试。
DBCC CHECKIDENT ('TestTable', RESEED, 0)
GO
其中0是identity
起始值
应该注意的是,如果所有数据都通过DELETE
从表中DELETE
(即没有WHERE
子句),那么只要a)权限允许,并且b)没有FK引用表(它出现在这里就是这种情况),使用TRUNCATE TABLE
将是首选,因为它会执行更有效的DELETE
并同时重置IDENTITY
种子。 以下详细信息摘自TRUNCATE TABLE的MSDN页面:
与DELETE语句相比,TRUNCATE TABLE具有以下优点:
使用更少的事务日志空间。
DELETE语句一次删除一行,并在每个删除行的事务日志中记录条目。 TRUNCATE TABLE通过释放用于存储表数据的数据页来删除数据,并仅在事务日志中记录页解除分配。
通常使用较少的锁。
当使用行锁执行DELETE语句时,表中的每一行都被锁定以供删除。 TRUNCATE TABLE总是锁定表(包括模式(SCH-M)锁)和页面,但不是每行。
毫无例外,表格中还剩下零页。
执行DELETE语句后,表格仍可以包含空白页面。 例如,如果没有至少一个独占(LCK_M_X)表锁,堆中的空页将无法解除分配。 如果删除操作不使用表锁,表(堆)将包含许多空白页。 对于索引,删除操作可以留下空白页面,但这些页面将通过后台清理过程快速解除分配。
如果表包含标识列,则该列的计数器将重置为为列定义的种子值。 如果未定义种子,则使用默认值1。 要保留身份计数器,请改为使用DELETE。
所以如下:
DELETE FROM [MyTable];
DBCC CHECKIDENT ('[MyTable]', RESEED, 0);
只是成为:
TRUNCATE TABLE [MyTable];
请参阅TRUNCATE TABLE
文档(上面链接)了解有关限制等的其他信息。
上一篇: Reset identity seed after deleting records in SQL Server
下一篇: Auto increment primary key in SQL Server Management Studio 2012