Zmiana IDENTITY
właściwość jest tak naprawdę tylko zmianą metadanych. Ale bezpośrednie zaktualizowanie metadanych wymaga uruchomienia instancji w trybie pojedynczego użytkownika i grzebania w niektórych kolumnach w sys.syscolpars
i jest nieudokumentowane/nieobsługiwane i nie jest czymś, co poleciłbym lub podałbym dodatkowe szczegóły.
Dla osób, które natkną się na tę odpowiedź w SQL Server 2012+ zdecydowanie najłatwiejszym sposobem osiągnięcia tego wyniku kolumny autoinkrementacji byłoby utworzenie SEQUENCE
obiekt i ustaw next value for seq
jako domyślna kolumna.
Alternatywnie lub w przypadku poprzednich wersji (od 2005 r.) obejście opisane w tym elemencie connect pokazuje w pełni obsługiwany sposób wykonania tego bez potrzeby określania rozmiaru operacji na danych przy użyciu ALTER TABLE...SWITCH
. O tym pisałem również na blogu MSDN tutaj. Chociaż kod do osiągnięcia tego nie jest bardzo prosty i istnieją ograniczenia - na przykład zmieniana tabela nie może być celem ograniczenia klucza obcego.
Przykładowy kod.
Ustaw tabelę testową bez identity
kolumna.
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
Zmień go, aby miał identity
kolumna (mniej lub bardziej natychmiastowa).
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;
Przetestuj wynik.
INSERT INTO dbo.tblFoo (filler,filler2)
OUTPUT inserted.*
VALUES ('foo','bar')
Daje
bar filler filler2
----------- --------- ---------
10001 foo bar
Posprzątaj
DROP TABLE dbo.tblFoo