协慌网

登录 贡献 社区

在 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 数据库不支持此功能,但现在支持。


多亏所罗门 · 鲁兹基(Solomon Rutzky), 命令的文档现已修复。

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

其中 0 是identity起始值

应该注意的是,如果所有数据都是通过DELETE (即,没有WHERE子句),则只要 a)权限允许,并且 b)没有引用该表的 FK(出现) (在这种情况下),最好使用TRUNCATE TABLE ,因为它可以更有效地执行DELETE并同时重置IDENTITY种子。以下详细信息来自 MSDN 页面的TRUNCATE TABLE

与 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文档(上面链接),以获取有关限制等的更多信息。