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