【问题标题】:Updating Identity Column of a table with consecutive numbers through SQL Stored Procedure通过 SQL 存储过程更新具有连续数字的表的标识列
【发布时间】:2025-12-13 02:20:03
【问题描述】:

从表中删除重复记录后, 我想用从 1 开始的连续编号更新表的标识列。这是我的表详细信息

id(identity(1,1)),
EmployeeID(int),
Punch_Time(datetime),
Deviceid(int)

我需要通过存储过程执行此操作。 当我在存储过程中尝试以下语句时

DECLARE @myVar int
        SET @myVar = 0
        set identity_insert TempTrans_Raw# ON
        UPDATE  TempTrans_Raw# SET  @myvar = Id = @myVar + 1
        set identity_insert TempTrans_Raw# off

出现错误,例如...无法更新身份列“Id” 请任何人建议如何使用从 1 开始的连续编号来更新该表的标识列。

【问题讨论】:

  • 身份从未被用作序列号,并且永远无法保证连续性。如果您确实需要序列号,请尝试添加另一列并填充它
  • @Raj : 除了新库还有其他解决方案吗?
  • 您可以删除并重新创建列,但如果您不关心内容,为什么需要该列?
  • 你的更新语句如下 SET IDENTITY_INSERT tablename ON UPDATE STATEMENT SET IDENTITY_INSERT tablename OFF

标签: sql sql-server sql-server-2008 stored-procedures


【解决方案1】:
--before running this make sure Foreign key constraints have been removed that reference the ID. 

--insert everything into a temp table
SELECT (ColumnList) --except identity column
INTO #tmpYourTable
FROM yourTable

--clear your table
DELETE FROM yourTable
-- reseed identity
DBCC CHECKIDENT('table', RESEED, new reseed value)
--insert back all the values 
INSERT INTO yourTable (ColumnList)
SELECT OtherCols FROM #tmpYourTable
--drop the temp table
DROP TABLE #tmpYourTable
GO

【讨论】:

    【解决方案2】:

    IDENTITY 关键字用于生成一个密钥,该密钥可以与 PRIMARY KEY 约束结合使用以获得技术密钥。这些键是技术性的,它们用于链接表记录。它们应该没有其他含义(例如排序顺序)。 SQL Server 不保证生成的 ID 是连续的。但是,它们确实保证您按顺序排列它们。 (所以你可能会得到 1, 2, 4, ...,但永远不会得到 1, 4, 2, ...)

    这是 IDENTITY 的文档:https://msdn.microsoft.com/de-de/library/ms186775.aspx

    我个人不喜欢保证生成的 ID 是有序的。除了提供对记录的引用之外,技术 ID 应该没有任何意义。您可以依赖订单,但如果订单是您感兴趣的信息,我认为您应该存储该信息(例如以时间戳的形式)。

    如果您想要一个数字来告诉您某条记录是第 5 或第 16 条记录,或者按顺序排列的任何记录,您始终可以使用 ROW_NUMBER 函数即时获取该数字。所以不需要生成和存储这样的连续值(当涉及到表上的并发事务时,这也可能很麻烦)。以下是获取该号码的方法:

    select
      row_number() over(order by id),
      employeeid,
      punch_time,
      deviceid
    from mytable;
    

    说了这么多;永远不需要更改 ID。如果您觉得需要,这是不恰当的桌子设计的标志。

    【讨论】:

      【解决方案3】:

      如果您确实需要序号,我建议您创建一个包含有效数字的表格(“OrderNumbers”),然后在向您的表格添加一行时让您编程从 OrderNumbers 中选择一行。

      如果您在一个事务中完成所有操作(即使用 Begin Tran 和 Commit),那么您可以在一行中获得一个数字,而不会出现任何问题。

      您应该在此列的两个表上都有主键或唯一键以防止重复。

      嗨, 亨里克

      【讨论】:

        【解决方案4】:

        查看此功能:DBCC CHECKIDENT('table', RESEED, new reseed value)

        【讨论】:

          最近更新 更多