【问题标题】:Alter column to be identity将列更改为身份
【发布时间】:2016-01-04 21:36:36
【问题描述】:

我已经阅读了以下关于一旦将列创建为常规 int 就不可能将列更改为标识的答案。

Adding an identity to an existing column

How to Alter a table for Identity Specification is identity SQL Server

How to alter column to identity(1,1)

但问题是我有一个表已迁移到一个新表,其中 ID 从一开始就没有声明为身份,因为很久以前使用 ID 身份创建的旧表缺少行清除历史数据。据我所知,如果我在新表上添加一个新列作为标识,它将自动按顺序创建列,我需要按原样保留旧表中的 ID,因为已经有数据链接到这些以前的ID。

如何将新表中的 ID 列转换为身份而不是顺序,而是使用旧表中的 ID?

【问题讨论】:

  • 您无法更新标识列。但是,如果您为该表打开 IDENTITY_INSERT,则可以提供一个值。本质上,您必须删除所有当前行并使用所需的标识值重新插入它们。
  • 从概念上讲,让新身份作为基于 X 的自增整数(其中 X = MAX([Your Old ID Column]) + 1)存在是否可以接受,然后更新它您希望将旧身份保留为其旧值的行上的身份字段?如果是这样,我将发布有关如何解决此问题的步骤作为正式答案 - 只是想确保我们首先在同一页面上。
  • @LDMJoe 您无法更新身份列。如果你知道一些更新它的方法,我会很感兴趣。
  • @SeanLange 这就是为什么我问“概念上” - 将通过填充非身份列,然后打开 IDENTITY_INSERT 并使用这些值设置为 OP 想要的填充一个新表。 OP 从来没有回答,其他人已经发布了我想要的答案,并且它已被接受,所以我认为我们已经完成了这个。

标签: sql-server sql-server-2008 identity alter-table


【解决方案1】:

你可以试试这个方法:

  1. 插入旧 ID 为 SET IDENTITY_INSERT <new table> ON 的行。这样您就可以插入自己的 ID。
  2. 重新设定身份,将其设置为最高 ID 值 +1 并使用 DBCC CHECKIDENT ('<new table>', RESEED, <max ID + 1>)。这将允许您的身份从最高 ID 增加并向前。

代码中有这样的东西:

-- Disable auto increment
SET IDENTITY_INSERT <new table> ON
-- <INSERT STUFF HERE>
SET IDENTITY_INSERT <new table> OFF

-- Reseed Identity from max ID
DECLARE @maxval Int
SET @maxval = ISNULL(
(
    SELECT
        MAX(<identity column>) + 1
    FROM <new table>
), 0)
DBCC CHECKIDENT ('<new table>', RESEED, @maxval)

编辑:这种方法当然需要您的 ID 列和身份。

【讨论】:

    【解决方案2】:

    如果您想要从以前的版本中复制的字段中没有空值,您可以首先通过执行 max(Id) 选择来确定最大 ID 是多少。然后使用 SSMS 添加您的新字段,当您将其设置为身份时,只需将 SEED 值设置为高于当前最大值的值,这样您就不会在新插入时发生冲突。

    【讨论】:

      【解决方案3】:

      我有一个在源文件、CSV 和生产表之间使用临时表的过程。临时表必须与 CSV 文件列匹配,此数据中没有 PK。

      为了查找 Azure 数据工厂失败前后的一组行,我将超过 2,000,000 行导入到一个临时表中。该进程在 Azure 中的 1,500,000 行处停止。

      错误是整数或字符串将被截断。

      这行代码在临时表中添加了一个PK并递增:

      ALTER TABLE ##FLATFILETEMPBDI ADD ROWNUM INT IDENTITY

      这将是获取行号的最简单解决方案。然后,我能够执行此查询以查找 1,500,000 之前和之后的行:

      SELECT  
        ROWNUM
        , PARTDESCRIPTION
        , LEN(PARTDESCRIPTION) AS LENDESCR
        , QUANTITY
        , ONORDER
        , PRICE
        , MANUFACTURERPARTNUMBER
      FROM ##FLATFILETEMPBDI 
      WHERE ROWNUM BETWEEN 1499990 AND 1500005
      

      完美运行 - 并没有计划那么简单,当任何人看到带有 IDENTITY 的 ALTER TABLE 可以为我进行编号时都感到惊讶。

      【讨论】:

        猜你喜欢
        • 2014-04-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-09-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-04-01
        相关资源
        最近更新 更多