sql >> Databasteknik >  >> RDS >> Sqlserver

SQL Server, Hur ställer man in automatisk ökning efter att ha skapat en tabell utan dataförlust?

Ändra IDENTITY egenskapen är egentligen bara en metadataändring. Men för att uppdatera metadata direkt krävs att instansen startas i enanvändarläge och att du stökar med några kolumner i sys.syscolpars och är odokumenterad/stödd och inte något jag skulle rekommendera eller kommer att ge några ytterligare detaljer om.

För personer som stöter på det här svaret på SQL Server 2012+ är det överlägset enklaste sättet att uppnå detta resultat av en automatisk ökningskolumn att skapa en SEQUENCE objekt och ställ in next value for seq som standardkolumn.

Alternativt, eller för tidigare versioner (från 2005 och framåt), visar lösningen som publicerats på det här anslutningsobjektet ett helt stödd sätt att göra detta utan behov av datastorleksoperationer med ALTER TABLE...SWITCH . Har även bloggat om på MSDN här. Även om koden för att uppnå detta inte är särskilt enkel och det finns begränsningar - som att tabellen ändras kan inte vara målet för en främmande nyckel-begränsning.

Exempelkod.

Sätt upp testtabell utan identity kolumn.

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

Ändra den så att den får en identity kolumn (mer eller mindre omedelbar).

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;

Testa resultatet.

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

Ger

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

Städa upp

DROP TABLE dbo.tblFoo


  1. Hur man kommenterar i SQL

  2. Hur man skapar historik ELLER granskar vyer från Change Data Capture-tabeller (CDC) i SQL Server - SQL Server Tutorial

  3. Exportera SQLite-databas till en CSV-fil

  4. 5 sätt att uppdatera data med en underfråga i Oracle SQL