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

SQL Server, Как да задам автоматично увеличение след създаване на таблица без загуба на данни?

Промяна на IDENTITY свойството наистина е промяна само на метаданни. Но за директно актуализиране на метаданните е необходимо да стартирате екземпляра в режим на един потребител и да се забърквате с някои колони в sys.syscolpars и е недокументиран/неподдържан и не е нещо, за което бих препоръчал или ще дам допълнителни подробности.

За хората, които се натъкват на този отговор на SQL Server 2012+, най-лесният начин за постигане на този резултат от автоматично увеличаваща се колона би бил да се създаде SEQUENCE обект и задайте next value for seq като колоната по подразбиране.

Алтернативно, или за предишни версии (от 2005 г. нататък), заобикалянето, публикувано в този елемент за свързване, показва напълно поддържан начин за извършване на това без нужда от операции с размер на данни с помощта на ALTER TABLE...SWITCH . Тук също блогвате за MSDN. Въпреки че кодът за постигане на това не е много прост и има ограничения - като например променяната таблица не може да бъде обект на ограничение за външен ключ.

Примерен код.

Настройте тестова таблица без identity колона.

CREATE TABLE dbo.tblFoo 
(
bar INT PRIMARY KEY,
filler CHAR(8000),
filler2 CHAR(49)
)


INSERT INTO dbo.tblFoo (bar)
SELECT TOP (10000) ROW_NUMBER() OVER (ORDER BY (SELECT 0))
FROM master..spt_values v1, master..spt_values v2

Променете го, за да има identity колона (повече или по-малко моментално).

BEGIN TRY;
    BEGIN TRANSACTION;

    /*Using DBCC CHECKIDENT('dbo.tblFoo') is slow so use dynamic SQL to
      set the correct seed in the table definition instead*/
    DECLARE @TableScript nvarchar(max)
    SELECT @TableScript = 
    '
    CREATE TABLE dbo.Destination(
        bar INT IDENTITY(' + 
                     CAST(ISNULL(MAX(bar),0)+1 AS VARCHAR) + ',1)  PRIMARY KEY,
        filler CHAR(8000),
        filler2 CHAR(49)
        )

        ALTER TABLE dbo.tblFoo SWITCH TO dbo.Destination;
    '       
    FROM dbo.tblFoo
    WITH (TABLOCKX,HOLDLOCK)

    EXEC(@TableScript)


    DROP TABLE dbo.tblFoo;

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


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

Тествайте резултата.

INSERT INTO dbo.tblFoo (filler,filler2) 
OUTPUT inserted.*
VALUES ('foo','bar')

Дава

bar         filler    filler2
----------- --------- ---------
10001       foo       bar      

Почистете

DROP TABLE dbo.tblFoo


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Регистърът на транзакциите на SQL Server, част 1:Основи на регистрирането

  2. Експортиране на таблица от база данни в csv файл

  3. Изследване на SQL Server 2014 SELECT INTO Parallelism

  4. Какво е проста програма или скрипт за команден ред за архивиране на бази данни на SQL сървър?

  5. Разлика между sys.parameters, sys.system_parameters и sys.all_parameters в SQL Server