sql >> Database >  >> RDS >> Sqlserver

SQL Server, Hoe stel ik automatisch ophogen in na het maken van een tabel zonder gegevensverlies?

De IDENTITY wijzigen eigenschap is echt een wijziging van de metadata. Maar om de metadata rechtstreeks bij te werken, moet u de instantie starten in de modus voor één gebruiker en wat rommelen met enkele kolommen in sys.syscolpars en is niet gedocumenteerd/niet ondersteund en niet iets dat ik zou aanbevelen of waar ik aanvullende details over zal geven.

Voor mensen die dit antwoord op SQL Server 2012+ tegenkomen, is verreweg de gemakkelijkste manier om dit resultaat van een automatisch oplopende kolom te bereiken, het maken van een SEQUENCE object en stel de next value for seq als standaard in de kolom.

Als alternatief, of voor eerdere versies (vanaf 2005), toont de tijdelijke oplossing die op dit connect-item is gepost een volledig ondersteunde manier om dit te doen zonder dat er gegevensbewerkingen nodig zijn met behulp van ALTER TABLE...SWITCH . Hier ook over geblogd op MSDN. Hoewel de code om dit te bereiken niet erg eenvoudig is en er beperkingen zijn - zoals de tabel die wordt gewijzigd, kan niet het doelwit zijn van een externe sleutelbeperking.

Voorbeeldcode.

Stel een testtabel in zonder identity kolom.

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

Wijzig het om een ​​identity te hebben kolom (min of meer direct).

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;

Test het resultaat.

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

Geeft

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

Opruimen

DROP TABLE dbo.tblFoo


  1. Hoe verbinding maken met MS SQL Server met behulp van Inno Setup?

  2. mysql twee kolommen primaire sleutel met automatische verhoging

  3. Service Broker-verbeteringen in SQL Server 2016

  4. Het transactielogboek voor de database is vol