IDENTITY 列重置编号

Posted

技术标签:

【中文标题】IDENTITY 列重置编号【英文标题】:IDENTITY Column reset numbering 【发布时间】:2018-06-17 12:01:51 【问题描述】:

我有一个带有 IDENTITY 列 (bigint) 的 SQL Server 表。

假设表包含 100 条记录,那么 IDENTITY 列的值将在 1-100 之间。

如果我删除了中间的一些记录,假设删除了标识值为 3、7、18、20 的行。

我需要将行重新编号以从 1 开始到 96,并且新记录从 97 继续。

如何实现?

【问题讨论】:

但我在一个审计表中有这个,与其他表没有关系。 【参考方案1】:

Jacob H 在 cmets 中所说的完全正确,IDENTITY 列并非旨在保存连续值。如果您DELETE 一行,那么您将丢失一个数字。但是,如果INSERT 失败,事务被回滚,或者(如果您使用的是旧版本的 SQL Server)服务器意外停止,那么您也会观察到相同的问题。 (在旧版本中,SQL Server 用于缓存一系列标识(1000)。如果服务器意外停止,则不会释放缓存,因此种子(在启动时)将是最大值旧缓存 +1。)

如果您需要获取序列号,则需要在您的SELECT 语句中使用ROW_NUMBER()。你需要类似的东西:

ROW_NUMBER() OVER (ORDER BY YourIDColumn) AS SequentialIdentity

编辑:如果您想有一种更永久的方式来获取“行号”,那么您可以创建一个VIEW,其中有一列包含来自ROW_NUMBER() 的序列标识的值。然后,不要在查询中引用表,而是引用视图。

【讨论】:

【参考方案2】:

正如@Jacob 在他的评论中所说,密钥并不是要更改的。一旦一行获得了一个键(身份),它应该保持不变,直到该行被删除。相反,我建议您添加一个可用于存储数字的新列。

请注意,新列需要维护,因为每次删除一行时,数字序列中都会出现一个间隙。这需要多久执行一次,可能是通过计划的作业每晚一次,或者立即使用数据库触发器。

您也可以通过仅在从数据库中获取数据时创建行编号列来跳过整个问题。查询可能如下所示:

SELECT RANK() OVER (ORDER BY KeyColumn) AS test, * FROM MyOwnTable ORDER BY test

【讨论】:

以上是关于IDENTITY 列重置编号的主要内容,如果未能解决你的问题,请参考以下文章

sql数据库中为列添加identity属性有啥用?

IDentity 是啥意思

Identity 自增长标识

SET IDENTITY_INSERT ON|OFF 的解惑

重置identity值

ASP.NET Identity 重置密码