将现有列转换为标识

时间:2013-10-25 08:05:29

标签: sql sql-server tsql sql-server-2012

我在SQL Server中有一个包含记录包的表。我想将主键ID列转换为标识列,而不会丢失数据。我想到了以下两种方法:

  1. 使用identity&创建一个新表删除现有的表格。
  2. 使用identity&创建一个新列删除现有列。
  3. 但很明显它们无法实施,因为保留记录是我的首要任务。

    还有其他办法吗?

5 个答案:

答案 0 :(得分:3)

这个解决方案违反了你的观点2,但没有别的办法,我认为你的目标是保留旧的价值观,因为没有别的意义......

您可以执行以下操作:

  1. 可以插入表格中的标识列:

    set identity_insert YourTable ON
    
  2. 使用标识向表中添加新ID列,并插入旧列中的值
  3. 关闭身份插入

    set identity_insert YourTable OFF
    
  4. 删除旧ID列
  5. 将新列重命名为旧名称
  6. 将其设为主键
  7. 唯一的问题可能是您的ID列已作为外键连接到其他表。然后你有一个删除旧列的问题... 在这种情况下,您必须在步骤3之后删除ID列上的外键约束,然后执行步骤4到6,然后重新创建外键约束。

答案 1 :(得分:2)

当您使用SQL Server 2012时,另一种可能的替代方法是创建一个序列对象,其表中已有最高ID +1的起始值,然后使用GET NEXT VALUE FOR为您的列创建默认约束并引用刚刚创建的序列对象。

答案 2 :(得分:0)

如果您可以直接访问服务器数据库,只需进入表格设计,选择PK列,然后将标识更改为"是"。确保将种子设置为该列的最大值。默认情况下,增量为1。保存桌面设计,你应该好好去。 enter image description here

答案 3 :(得分:0)

考虑源表不是太大:

  1. 创建新表(具有IDENTITY)
  2. 从现有表填充新表(IDENTITY_INSERT为ON)
  3. 删除旧表(首先删除任何现有FK)
  4. 将新表重命名为旧表(如果需要,请重新建立FK)

       -- Create Sample Existing Table
       DROP TABLE IF EXISTS #tblTest
       CREATE TABLE #tblTest
       (
            ID      INT NOT NULL
            , Val   VARCHAR(10) NOT NULL
        )
    
        INSERT INTO #tblTest 
        (
            ID
            , Val
        )
        VALUES 
            (1, 'a')
            , (2, 'b')
            , (4, 'c')
        GO
    
        -- Create and Populate New Table (with IDENTITY_INSERT ON)
        DROP TABLE IF EXISTS #tblTestNew
        CREATE TABLE #tblTestNew
        (
            ID      INT IDENTITY(1, 1) NOT NULL 
            , Val   VARCHAR(10) NOT NULL
        )
    
        SET IDENTITY_INSERT #tblTestNew ON
    
        INSERT INTO #tblTestNew 
        (
            ID
            , Val
        )
        (
            SELECT
                #tblTest.ID
                , #tblTest.Val
            FROM
                #tblTest
        )
    
        SET IDENTITY_INSERT #tblTestNew OFF
        GO
    
        -- Rename Existing Table to Old (can use sp_rename instead, but I can't for temp tables)
        SELECT * INTO #tblTestOld FROM #tblTest
        DROP TABLE #tblTest
        GO
    
        -- Rename New Table to Existing (can use sp_rename instead, but I can't for temp tables)
        SELECT * INTO #tblTest FROM #tblTestNew
        DROP TABLE #tblTestNew
        GO
    
        -- Test Inserting new record
        INSERT INTO #tblTest (Val)
        VALUES ('d')
    
        -- Verify Results
        SELECT * FROM #tblTest
        EXEC tempdb.sys.sp_help @objname = N'#tblTest'
    
        --  Drop 'Old' Table (when ready)
        DROP TABLE IF EXISTS #tblTestOld
    
        -- Cleanup
        DROP TABLE IF EXISTS #tblTest
        DROP TABLE IF EXISTS #tblTestNew
        DROP TABLE IF EXISTS #tblTestOld
    

如果表很大,请考虑日志增长,恢复模型,可能的单用户模式等。

答案 4 :(得分:-2)

create table t1 (col1 int, col2 varchar(10))

insert into t1 values (10, 'olddata')

- 添加标识col

alter table t1 add col3 int identity(1,1)

GO

- 重命名或删除旧列

alter table t1 drop column col1

- 将新col重命名为旧col名称

exec sp_rename 't1.col3', 'col1', 'column'

GO

- 添加新测试,评论表

insert into t1 values ( 'newdata')

从t1

中选择*