Re-seeding a large sql table

Using version:

Microsoft SQL Server 2008 R2 (SP3-OD) (KB3144114) - 10.50.6542.0 (Intel X86) 
Feb 22 2016 18:12:09 
Copyright (c) Microsoft Corporation
Standard Edition on Windows NT 5.2 <X86> (Build : )

I have a heavy table (135K rows), that I moved from another DB.
It transferred with the [id] column being a standard int column instead of it being the key & seed column.
When trying to edit that field to become an identity specification, with a seed value, its errors out and gives me this error:

  • How to rename something in SQL Server that has square brackets in the name?
  • Return number of rows affected by UPDATE statements
  • Foreign key with large table vs small table
  • SQL select print out results of stored procedue
  • Access to Result sets from within Stored procedures Transact-SQL SQL Server
  • how to write a query to satisfy search conditon
  • Execution Timeout Expired.  
    The timeout period elapsed prior to completion of the operation...
    

    I even tried deleting that column, to try recreate it later, but i get the same issue.

    Thanks

    UPDATE:

    Table structure:

    CREATE TABLE [dbo].[tblEmailsSent](
        [id] [int] IDENTITY(1,1) NOT NULL,  -- this is what it should be. currently its just an `[int] NOT NULL`
        [Sent] [datetime] NULL,
        [SentByUser] [nvarchar](50) NULL,
        [ToEmail] [nvarchar](150) NULL,
        [StudentID] [int] NULL,
        [SubjectLine] [nvarchar](200) NULL,
        [MessageContent] [nvarchar](max) NULL,
        [ReadStatus] [bit] NULL,
        [Folder] [nvarchar](50) NULL,
     CONSTRAINT [PK_tblMessages] PRIMARY KEY CLUSTERED 
    (
        [id] ASC
    )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
    ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
    
    GO
    

    One Solution collect form web for “Re-seeding a large sql table”

    I think that your question is a duplicate of Adding an identity to an existing column. That question above has an answer that should be perfect for your situation. I’ll reproduce its essential part here below.


    But before that, let’s clarify why you see the timeout error.

    You are trying to add the IDENTITY property to existing column. And you are using SSMS GUI for it. A simple ALTER COLUMN statement can’t do it and even if it could, SSMS generates a script that creates a new table, copies over the data into the new table, drops the old table and renames the new table to the old name. When you do this operation via SSMS GUI it runs its scripts with a predefined timeout of 30 seconds.

    ssms timeout

    Of course, you can change this setting in SSMS and increase the timeout, but there is a much better way.

    1. Simple/lazy way

    Use SSMS GUI to change the column definition, but then instead of clicking “Save”, click “Generate Change Script” in the table designer.

    ssms generate change script

    Then save this script to a file and review the generated T-SQL code that GUI runs behind the scene.

    You’ll see that it creates a temp table with the required schema, copies data over, re-creates foreign keys and indexes, drops the old table and renames the new table.

    The script itself is usually correct, but pay close attention to transactions in it. For some reason SSMS often doesn’t use a single transaction for the whole operation, but several transactions. I’d recommend to manually review the script and make sure that there is only one BEGIN TRANSACTION at the top and one COMMIT in the end. You don’t want to end up with a half-done operation with, say, a table where all indexes and foreign keys were dropped.

    If it is a one-off operation, it could be enough for you. Your table is only 2.4GB, so it may take few minutes, but it should not be hours.

    If you run the T-SQL script yourself in SSMS, then by default there is no timeout. You can stop it yourself if it takes too long.

    ssms run


    1. Smart and fast way to do it is described in details in this answer by Justin Grant.

    The main idea is to use the ALTER TABLE...SWITCH statement to make the change only touching the metadata without touching each page of the table.

    BEGIN TRANSACTION;
    
    -- create a new table with required schema
    CREATE TABLE [dbo].[NEW_tblEmailsSent](
        [id] [int] IDENTITY(1,1) NOT NULL,
        [Sent] [datetime] NULL,
        [SentByUser] [nvarchar](50) NULL,
        [ToEmail] [nvarchar](150) NULL,
        [StudentID] [int] NULL,
        [SubjectLine] [nvarchar](200) NULL,
        [MessageContent] [nvarchar](max) NULL,
        [ReadStatus] [bit] NULL,
        [Folder] [nvarchar](50) NULL,
     CONSTRAINT [PK_tblEmailsSent] PRIMARY KEY CLUSTERED 
    (
        [id] ASC
    )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
    ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
    
    -- switch the tables
    ALTER TABLE [dbo].[tblEmailsSent] SWITCH TO [dbo].[NEW_tblEmailsSent];
    
    -- drop the original (now empty) table
    DROP TABLE [dbo].[tblEmailsSent];
    
    -- rename new table to old table's name
    EXEC sp_rename 'NEW_tblEmailsSent','tblEmailsSent';
    
    COMMIT;
    

    After the new table has IDENTITY property you normally should set the current identity value to the maximum of the actual values in your table. If you don’t do it, new rows inserted into the table would start from 1.

    One way to do it is to run DBCC CHECKIDENT after you switched the tables:

    DBCC CHECKIDENT('dbo.tblEmailsSent')
    

    Alternatively, you can specify the new seed in the table definition:

    CREATE TABLE [dbo].[NEW_tblEmailsSent](
        [id] [int] IDENTITY(<max value of id + 1>, 1) NOT NULL,
    
    MS SQL Server is a Microsoft SQL Database product, include sql server standard, sql server management studio, sql server express and so on.