6

大家好。我的数据库中有一张表,里面有大约一千条记录。我想重置标识列,以便所有 ID 再次按顺序排列。我在看这个,但我假设它只适用于空桌子

当前表

ID    |    Name
1           Joe
2           Phil
5           Jan
88          Rob

所需表

ID    |    Name
1           Joe
2           Phil
3           Jan
4           Rob

提前致谢

4

6 回答 6

5

最简单的方法是复制当前表,修复任何 parentid 问题,删除它,然后重命名新表。

您也可以暂时删除IDENTITY并尝试以下操作:

;WITH TBL AS
(
  SELECT *, ROW_NUMBER(ORDER BY ID) AS RN
  FROM CURRENT_TABLE
)
UPDATE TBL
SET ID = RN

或者,如果您不关心记录的顺序,这

DECLARE INT @id;
SET @id = 0;

UPDATE CURRENT_TABLE
SET @id = ID = @id + 1;
于 2010-05-08T00:31:17.793 回答
3

一种方法,将其包装在事务中

select id,name into #temp from YourTable

      truncate table YourTable

      insert YourTable (name)
      select name from #temp
于 2010-05-08T00:38:18.650 回答
1

快速解决方案是:

  1. 创建具有相同架构的新表
  2. 将旧表复制到新表(标识列除外)
  3. 删除旧表
  4. 重命名新表
于 2010-05-08T00:33:35.000 回答
1

因为您在同一个表中有外键(根据您的评论),所以您需要在某处保留从旧到新的映射并重新设置外键以匹配新身份。

有很多方法可以做到这一点,但我强烈质疑更新主键的必要性,特别是因为你已经有外键引用它们,而且它只是一个代理键。这不像您将代理键更改为 GUID 或特殊的东西。

于 2010-05-08T00:38:11.350 回答
1

这是我重置身份字段的方法。上述版本的 CTE(公用表表达式)太过分了。只需使用带有连接的简单更新语句使用当前行号来更新标识列:

UPDATE [YourTable] SET ID = rn.RowNumber FROM [YourTable]
JOIN (SELECT ID, ROW_NUMBER() OVER (ORDER BY ID) AS RowNumber
  FROM [YourTable]) rn ON rn.ID = [YourTable].ID

该语句可以重构为更简单。如果是这样,我很想看到更简单的版本。

我希望这可以帮助别人。

于 2010-10-28T18:38:14.510 回答
-1

使用DBCC CHECKIDENT。该表不需要为空:

  • DBCC CHECKIDENT ( table_name, NORESEED)

当前标识值未重置。DBCC CHECKIDENT 返回当前标识值和标识列的当前最大值。如果两个值不相同,则应重置标识值以避免值序列中的潜在错误或间隙。

  • DBCC CHECKIDENT ( table_name )或者DBCC CHECKIDENT ( table_name, RESEED )

如果表的当前标识值小于标识列中存储的最大标识值,则使用标识列中的最大值对其进行重置。

  • DBCC CHECKIDENT ( table_name, RESEED, new_reseed_value )

当前标识值设置为 new_reseed_value。如果自创建表以来没有向表中插入任何行,或者如果使用 TRUNCATE TABLE 语句删除了所有行,则在运行 DBCC CHECKIDENT 后插入的第一行使用 new_reseed_value 作为标识。否则,插入的下一行使用 new_reseed_value + 当前增量值。

如果表不为空,则将标识值设置为小于标识列中最大值的数字可能会导致以下情况之一:

  • 如果标识列上存在 PRIMARY KEY 或 UNIQUE 约束,则在以后向表中插入操作时将生成错误消息 2627,因为生成的标识值将与现有值冲突。

  • 如果 PRIMARY KEY 或 UNIQUE 约束不存在,以后的插入操作将导致重复的标识值。

于 2010-05-08T00:25:11.083 回答