Billz
Billz

Reputation: 1097

Convert an existing Column to Identity

I have a table in SQL Server with bundle of records. I want to convert the ID column which is Primary Key to an identity Column without loss of data. I thought of the following two approaches:

  1. Create a new table with identity & drop the existing table.
  2. Create a new column with identity & drop the existing column.

but it's clear that they can not be implemented because keeping records is my first priority.

Is there another way to do this?

Upvotes: 12

Views: 25342

Answers (6)

Robert
Robert

Reputation: 11

It is simple.

  1. Put the table in DESIGN mode
  2. Change the column to be an IDENTITY specification
  3. Create a change script
  4. Copy the script and open a query window to paste it into
  5. Run the script

The script will handle creating a temp table, setting the identity insert, dropping the existing table, and renaming the temp table.

Upvotes: 0

Mike Zach
Mike Zach

Reputation: 1

Considering the source table isn't too big:

  1. Create new table (with IDENTITY)
  2. Populate new table from existing table (with IDENTITY_INSERT ON)
  3. Drop old table (drop any existing FKs first)
  4. Rename new table to old name (re-establish FKs if needed)

       -- 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
    

If the table is very large, consider the log growth, Recovery Model, possible single-user mode, etc.

Upvotes: 0

Red_Phoenix
Red_Phoenix

Reputation: 507

If you have direct access to the Server Database, just go into the design of the table, select the PK column, and change the identity to "Yes". Make sure you set your seed to the max value of that column. The increment is 1 by default. Save the table design and you should be good to go. enter image description here

Upvotes: 3

kinske
kinske

Reputation: 607

This solution violates your point 2, but there is no other way and I think your aim is to keep the old values, because nothing else makes sense...

You could do the following:

  1. make it possible to insert into identity columns in your table:

    set identity_insert YourTable ON
    
  2. add a new ID column to your table with identity and insert the values from your old columns
  3. turn identity insert off

    set identity_insert YourTable OFF
    
  4. delete old ID column
  5. rename new column to old name
  6. make it to the primary key

The only problem could be that you have your ID column already connected as foreign key to other tables. Then you have a problem with deleting the old column... In this case you have to drop the foreign key constraints on your ID column after step 3, then do step 4 to 6 and then recreate your foreign key constraints.

Upvotes: 7

steoleary
steoleary

Reputation: 9298

As you are using SQL Server 2012, another possible alternative could be to create a sequence object that has a starting value of the highest ID +1 already in your table, then create a default constraint for your column using GET NEXT VALUE FOR and reference your sequence object you just created.

Upvotes: 4

vhadalgi
vhadalgi

Reputation: 7189

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

insert into t1 values (10, 'olddata')

--add identity col

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

GO

--rename or remove old column

alter table t1 drop column col1

--rename new col to old col name

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

GO

--add new test , review table

insert into t1 values ( 'newdata')

select * from t1

Upvotes: -1

Related Questions