sql >> Database teknologi >  >> RDS >> Sqlserver

SQL Server, hvordan indstilles automatisk stigning efter oprettelse af en tabel uden tab af data?

Ændring af IDENTITY egenskab er virkelig kun en metadata-ændring. Men for at opdatere metadataene direkte kræver det at starte instansen i enkeltbrugertilstand og rode rundt med nogle kolonner i sys.syscolpars og er udokumenteret/ikke-understøttet og ikke noget, jeg vil anbefale eller vil give yderligere detaljer om.

For folk, der støder på dette svar på SQL Server 2012+, ville langt den nemmeste måde at opnå dette resultat af en automatisk stigningskolonne på være at oprette en SEQUENCE objekt og indstil next value for seq som kolonnens standard.

Alternativt, eller for tidligere versioner (fra 2005 og frem), viser den løsning, der er opslået på dette forbindelseselement, en fuldstændig understøttet måde at gøre dette på uden behov for størrelse af dataoperationer ved hjælp af ALTER TABLE...SWITCH . Har også blogget om på MSDN her. Selvom koden for at opnå dette ikke er særlig enkel, og der er begrænsninger - såsom at tabellen ændres, kan ikke være målet for en fremmednøglebegrænsning.

Eksempelkode.

Opsæt testtabel uden identity kolonne.

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

Rediger den til at have en identity kolonne (mere eller mindre øjeblikkelig).

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

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

Giver

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

Ryd op

DROP TABLE dbo.tblFoo


  1. Indsættelse af forberedt erklæring til database - PSQL

  2. SQL-forespørgsel til at sammenligne produktsalg efter måned

  3. PDOException "kunne ikke finde driver"

  4. Værdier vises ikke med indledende nul i oracle