【问题标题】:Reseeding Identity Column to Original Value将标识列重新设置为原始值
【发布时间】:2014-08-13 14:41:32
【问题描述】:

有没有办法将标识列重新设置为原始值?目前我有这个IDENTITY(1,1) 作为我的表定义。我试过用这种方法重新播种:

DBCC CHECKIDENT (Table1, reseed, 1)

但我注意到,SQL 实际上将其重新设置为当前种子 + 新种子值,因此当我插入新行时,它会从 2 而不是 1 开始自动递增计数。我也尝试过制作新的重新种子值0,但之后我插入的所有行最终都为 1,并且该列不再自动递增。

顺便说一句,如果有帮助,我需要此列将其自动递增计数重新设置为零,因为我需要每个月重新开始计数。我在为此设置插入后触发,但重新播种给我带来了一些麻烦。

【问题讨论】:

  • 你为什么要这样做?
  • 在重新启动 IDENTITY 列的值之前,您是否删除/截断 Table1
  • 我需要这样做,因为我需要跟踪传入的工作,我们的工作管理系统将每个工作分为两部分:1. 四位数 MMYY(例如 0714 = 2014 年 7 月)和2. 5 位数字 00001(IDENTITY 列)。并且每次更改月份时,5位数字都必须重新计算。我不会删除或截断任何列。
  • 不要这样做。你有哪个 SQL Server 版本? SELECT @@VERSION
  • 我相信是 Microsoft SQL Server 2012

标签: sql sql-server auto-increment identity-column


【解决方案1】:

以下声明:

DBCC CHECKIDENT('YourTableName', RESEED, 1);

告诉数据库类似于:

“嘿数据库!YourTableName 表中的最高标识值是#1,因此下一个插入的记录应该使用标识值#2。” p>

这解释了为什么当您使用语句对其进行 RESEED 时,您的表以标识值 2 开头。

更具体地说,Microsoft 对 DBCC CHECKIDENT() 的帮助表明:

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

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

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

听起来您想将表的初始起始种子值从 1 更改为 0。考虑到这一点,您需要修改表的定义以使用:

IDENTITY(0,1);

我希望这会有所帮助。祝你好运。

【讨论】:

    【解决方案2】:

    不是真正的答案,但评论太长了,确实涵盖了问题。

    我也尝试将新的种子值设为 0,但之后我插入的所有行最终都为 1,并且该列不再自动递增。

    我无法重现这种行为:

    IF OBJECT_ID(N'dbo.T', 'U') IS NOT NULL
        DROP TABLE dbo.T;
    
    CREATE TABLE dbo.T(ID INT IDENTITY(1,1) NOT NULL);
    INSERT dbo.T OUTPUT inserted.* DEFAULT VALUES;
    -- OUTPUTS 1
    
    DELETE dbo.T;
    DBCC CHECKIDENT ('dbo.T', RESEED, 0);
    INSERT dbo.T OUTPUT inserted.* DEFAULT VALUES;
    -- OUTPUTS 1, I.E. RESEED TO 0 HAS WORKED FINE
    
    INSERT dbo.T OUTPUT inserted.* DEFAULT VALUES;
    -- OUTPUTS 2, SHOWS INCREMENT IS WORKING AS EXPECTED
    
    IF OBJECT_ID(N'dbo.T', 'U') IS NOT NULL
        DROP TABLE dbo.T;
    

    值得注意的是,对于空表,如果您使用 0 作为 RESEED 值,则标识将从 0 开始,即

    TRUNCATE TABLE dbo.T;
    DBCC CHECKIDENT ('dbo.T', RESEED, 0);
    INSERT dbo.T OUTPUT inserted.* DEFAULT VALUES;
    

    将输出 0 作为插入的 ID。

    【讨论】:

      【解决方案3】:

      我相信这样做的唯一方法是将select您的所有数据放入第二个表中。

      然后你可以发出命令truncate table Table1

      这将重置标识列。

      然后您将所有临时保存的数据重新插入到主表中(不插入旧标识)。

      示例...

      注意:一次运行每个代码块,检查计数,不要运行整个代码 - 我已经将“危险”位注释掉以防万一

      /** select all columns but NOT the id into a temp location (dont use a # table) **/
      SELECT col1, col2, col3, col4, col5
      INTO tmpTable
      FROM Table1
      
      /** before truncation, double check counts in both match!! **/
      -- SELECT COUNT(2) FROM tmpTable
      -- SELECT COUNT(2) from Table1
      
      -- TRUNCATE TABLE Table1
      
      INSERT INTO Table1
      SELECT col1, col2, col3, col4, col5
      FROM tmpTable
      
      /** before you drop temp table, make sure Table1 is ok! **/
      -- SELECT COUNT(2) FROM tmpTable
      -- SELECT COUNT(2) from Table1
      
      -- DROP TABLE tmpTable
      

      这里有一个快速测试来演示——我插入 8 行,删除 1 行,然后重新插入。它们已正确重新编号。

      IF OBJECT_ID('DBO.TEST') IS NOT NULL DROP TABLE TEST
      IF OBJECT_ID('DBO.TMP') IS NOT NULL DROP TABLE TMP
      
      CREATE TABLE TEST ([ID] INT IDENTITY(1,1), [SOMESTRING] NVARCHAR(50))
      
      INSERT INTO TEST([SOMESTRING])
      SELECT 'HI' UNION
      SELECT 'THESE' UNION
      SELECT 'ARE' UNION
      SELECT 'SOME' UNION
      SELECT 'STRINGS' UNION
      SELECT 'JUST' UNION
      SELECT 'TO' UNION
      SELECT 'DEOMONSTRATE'
      
      SELECT *
      FROM TEST
      
      DELETE FROM TEST
      WHERE SOMESTRING='SOME'
      
      SELECT SOMESTRING
      INTO TMP
      FROM TEST
      
      TRUNCATE TABLE TEST
      
      INSERT INTO TEST
      SELECT SOMESTRING
      FROM TMP
      
      SELECT * FROM TEST
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-12-08
        • 1970-01-01
        • 2023-04-07
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多