我有一个带有IDENTITY
列(bigint
)的SQL Server表。
假设该表包含100条记录,那么IDENTITY
列的值将为1-100。
如果我删除其中的一些记录,那么就说删除了标识值为3,7,18,20的行。
我需要重新编号行,从1到96开始,新记录从97继续。
如何实现?
答案 0 :(得分:2)
Jacob H在评论中说的是完全正确的,IDENTITY
列不是为了保存连续值而设计的。如果您DELETE
一行,那么您将错过一个数字。但是,如果INSERT
失败,则回滚事务,或者(如果您使用旧版本的SQL Server)服务器意外停止,那么您也会遇到同样的问题。 (在旧版本中,SQL Server用于缓存一系列Identities(1000)。如果服务器意外停止,则缓存不会被释放,因此种子(启动时)将是最大值旧缓存+1。)
如果您需要获取序号,则需要在ROW_NUMBER()
语句中使用SELECT
。你需要这样的东西:
ROW_NUMBER() OVER (ORDER BY YourIDColumn) AS SequentialIdentity
编辑:如果您想要更长久的方式获取"行号",那么您可以创建一个VIEW
,其中包含一个包含您的值的列来自ROW_NUMBER()
的顺序身份。然后,不要在查询中引用表,而是引用视图。
答案 1 :(得分:1)
正如@Jacob在评论中所说,关键并不是要改变。一旦一行有一个密钥(标识),它应该保持不变,直到该行被删除。我建议您添加一个可用于存储数字的新列。
请注意,虽然需要维护新列,因为每次删除行时数字序列中的间隙。这种情况需要多长时间才能完成,可能取决于计划作业每晚一次,或者立即使用数据库触发器。
您也可以通过仅在从数据库中提取数据时创建行编号列来跳过整个问题。查询可能如下所示:
SELECT RANK() OVER (ORDER BY KeyColumn) AS test, * FROM MyOwnTable ORDER BY test