【问题标题】:How do I add the identity property to an existing column in SQL Server如何将标识属性添加到 SQL Server 中的现有列
【发布时间】:2008-11-13 20:47:11
【问题描述】:

在 SQL Server(在我的例子中,2005)中,如何使用 T-SQL 将标识属性添加到现有表列?

类似:

alter table tblFoo 
    alter column bar identity(1,1)

【问题讨论】:

  • Funny... SQL Server 2005 Compact edition 有这种语法,但 server edition 没有...
  • Azure SQL 也没有这种语法。
  • 赏金将转到可以执行此操作的 TSQL 脚本。 ( sig: spSetIdentity('TableName', 'Id') )
  • @Martin,确保 2008 年是有效要求(即使问题最初是 2005 年)
  • 如果您使用的 SKU 支持分区 this is possible as a meta data only change.

标签: sql-server tsql identity


【解决方案1】:

我不相信你能做到。最好的办法是创建一个新的标识列并使用标识插入命令复制数据(如果您确实想保留旧值)。

这是一篇不错的文章,详细描述了该过程: http://www.mssqltips.com/tip.asp?tip=1397

【讨论】:

  • 您说得对,当前版本的 SQL Server 无法做到这一点。
  • @Brent,这里的副作用是列顺序会随着这个技巧而改变
  • 列顺序只有在您执行“SELECT *”时才会出现问题,我似乎记得它是/正在被 SQL Server 诊断工具分类为警告(不记得哪一个)。
  • @Sam,赏金有什么用?保持列的顺序?如果是这样,您需要创建一个临时表,将所有数据复制到其中,然后使用正确的列顺序重新创建表并将数据复制回来。 Management Studio 可以为您执行此操作,但这只有在您没有脚本时才有用。 Visual Studio DB 版可以创建一个更改脚本,负责重新排序列...
  • @Sefen ... 是的,赏金是用于保留秩序并模拟管理工作室所做工作的 TSQL 脚本。
【解决方案2】:

Vikash 发布的解决方案不起作用;它在 SQL Management Studio(2005 年,如 OP 指定)中产生“语法错误”错误。 SQL Server 的“精简版”支持这种操作只是一个捷径,因为真正的过程更像是 Robert & JohnFX 所说的——创建重复表、填充数据、重命名原始表和新表适当的。

如果您想保留需要成为身份的字段中已经存在的值,您可以执行以下操作:

CREATE TABLE tname2 (etc.)
INSERT INTO tname2 FROM tname1

DROP TABLE tname1
CREATE TABLE tname1 (with IDENTITY specified)

SET IDENTITY_INSERT tname1 ON
INSERT INTO tname1 FROM tname2
SET IDENTITY_INSERT tname1 OFF

DROP tname2

当然,不建议删除并重新创建 实时代码 使用的表 (tname1)! :)

【讨论】:

  • 这也是使用 Azure SQL 表所必需的。
  • 首先创建另一个表是唯一的方法,因为如果您尝试创建另一个列并重命名它,则无法使用旧数据更新标识列,谢谢
【解决方案3】:

表格是否已填充?如果不删除并重新创建表。

如果填充了该列中已经存在哪些值?如果它们是您不想保留的值。

根据需要创建一个新表,将旧表中的记录加载到新表中,然后让数据库正常填充标识列。重命名您的原始表并将新表重命名为正确的名称:)。

最后,如果您希望标识的列当前包含主键值并且已被其他表引用,那么您将需要完全重新考虑,如果您确定这是您想要做的:)

【讨论】:

    【解决方案4】:

    没有直接的方法,除了:

    A) 通过 SQL 即:

    -- make sure you have the correct CREATE TABLE script ready with IDENTITY
    
    SELECT * INTO abcTable_copy FROM abcTable
    
    DROP TABLE abcTable
    
    CREATE TABLE abcTable -- this time with the IDENTITY column
    
    SET IDENTITY_INSERT abcTable ON
    
    INSERT INTO abcTable (..specify all columns!) FROM (..specify all columns!) abcTable_copy
    
    SET INDENTITY_INSERT abcTable OFF
    
    DROP TABLE abcTable_copy 
    
    -- I would suggest to verify the contents of both tables 
    -- before dropping the copy table
    

    B) 通过 MSSMS,这将在后台执行完全相同的操作,但会减少胖手指。

    • 在 MSSMS 对象资源管理器中右键单击需要修改的表
    • 选择“设计”选择要添加 IDENTITY 的列
    • 将身份设置从“否”更改为“是”(可能是种子)
    • Ctr+S 表格

    这将删除并重新创建包含所有原始数据的表。 如果您收到警告:

    转到 MSSMS 工具 -> 选项 -> 设计器 -> 表和数据库设计器 并取消选中选项“防止保存需要重新创建表的更改”

    注意事项:

    1. 在您执行此操作之前,您的数据库有足够的磁盘空间
    2. 数据库未使用(尤其是您正在更改的表)
    3. 确保在执行之前备份您的数据库
    4. 如果表有很多数据(超过 1G),请先在其他地方尝试 在实际数据库中使用之前

    【讨论】:

      【解决方案5】:
      1. 创建一个新表

        SELECT * INTO Table_New FROM Table_Current WHERE 1 = 0;
        
      2. 从新表中删除列

        Alter table Table_New drop column id;
        
      3. 添加具有标识的列

        Alter table Table_New add id int primary key identity; 
        
      4. 获取新表中的所有数据

        SET IDENTITY_INSERT Table_New ON;
        INSERT INTO Table_New (id, Name,CreatedDate,Modified) 
        SELECT id, Name,CreatedDate,Modified FROM Table_Current;
        SET IDENTITY_INSERT Table_New OFF;
        
      5. 删除旧表

        drop table Table_Current;
        
      6. 将新表重命名为旧表

        EXEC sp_rename 'Table_New', 'Table_Current';
        

      【讨论】:

        【解决方案6】:
        alter table tablename 
        alter column columnname 
        add Identity(100,1)
        

        【讨论】:

        • 这适用于您的列 MAX 为 100。第一个参数应该是您列中 MAX 的值 =。
        • 此语法也不适用于 SQL Server 2008 R2。
        猜你喜欢
        • 1970-01-01
        • 2012-01-29
        • 2012-05-10
        • 1970-01-01
        • 2016-05-11
        • 1970-01-01
        • 1970-01-01
        • 2011-04-11
        • 1970-01-01
        相关资源
        最近更新 更多