Sqlserver
 sql >> база данни >  >> RDS >> Sqlserver

Как да добавите колона за идентичност към съществуваща таблица на база данни, която има голям брой редове

Цялостният процес вероятно ще бъде много по-бавен с повече общи разходи за заключване, но ако ви интересува само размерът на регистрационния файл на транзакциите, можете да опитате следното.

  1. Добавяне на nullable integer колона без идентичност (промяна само на метаданните).
  2. Напишете код, за да актуализирате това с уникални последователни цели числа на партиди. Това ще намали размера на всяка отделна транзакция и ще запази размера на регистрационния файл нисък (приемайки прост модел за възстановяване). Моят код по-долу прави това на партиди от 100, надявам се, че имате съществуващ PK, който можете да използвате, за да продължите от там, където сте спрели, вместо многократните сканирания, които ще отнемат все повече време към края.
  3. използвайте ALTER TABLE ... ALTER COLUMN за да маркирате колоната като NOT NULL . Това ще изисква цялата таблица да бъде заключена и сканирана, за да потвърди промяната, но няма да изисква много регистриране.
  4. Използвайте ALTER TABLE ... SWITCH за да направите колоната колона за идентичност. Това е промяна само на метаданни.

Примерен код по-долу

/*Set up test table with just one column*/

CREATE TABLE table_1 ( original_column INT )
INSERT  INTO table_1
        SELECT DISTINCT
                number
        FROM    master..spt_values



/*Step 1 */
ALTER TABLE table_1 ADD id INT NULL



/*Step 2 */
DECLARE @Counter INT = 0 ,
    @PrevCounter INT = -1

WHILE @PrevCounter <> @Counter 
    BEGIN
        SET @PrevCounter = @Counter;
        WITH    T AS ( SELECT TOP 100
                                * ,
                                ROW_NUMBER() OVER ( ORDER BY @@SPID )
                                + @Counter AS new_id
                       FROM     table_1
                       WHERE    id IS NULL
                     )
            UPDATE  T
            SET     id = new_id
        SET @Counter = @Counter + @@ROWCOUNT
    END


BEGIN TRY;
    BEGIN TRANSACTION ;
     /*Step 3 */
    ALTER TABLE table_1 ALTER COLUMN id INT NOT NULL

    /*Step 4 */
    DECLARE @TableScript NVARCHAR(MAX) = '
    CREATE TABLE dbo.Destination(
        original_column INT,
        id INT IDENTITY(' + CAST(@Counter + 1 AS VARCHAR) + ',1)
        )

        ALTER TABLE dbo.table_1 SWITCH TO dbo.Destination;
    '       

    EXEC(@TableScript)


    DROP TABLE table_1 ;

    EXECUTE sp_rename N'dbo.Destination', N'table_1', 'OBJECT' ;


    COMMIT TRANSACTION ;
END TRY
BEGIN CATCH
    IF XACT_STATE() <> 0 
        ROLLBACK TRANSACTION ;
    PRINT ERROR_MESSAGE() ;
END CATCH ;


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Използвайте sys.trigger_event_types, за да изброите типовете тригерни събития в SQL Server

  2. Как да получите максимални и минимални стойности от таблица с помощта на агрегатна функция - SQL Server / TSQL урок, част 129

  3. Защо не мога да се свържа с моята база данни mssql с помощта на PHP?

  4. Използвайте SERVERPROPERTY(), за да получите информация за сървъра в SQL Server

  5. Как да заявите този изход в SQL сървър