Промяна на IDENTITY
свойството наистина е промяна само на метаданни. Но за директно актуализиране на метаданните е необходимо да стартирате екземпляра в режим на един потребител и да се забърквате с някои колони в sys.syscolpars
и е недокументиран/неподдържан и не е нещо, за което бих препоръчал или ще дам допълнителни подробности.
За хората, които се натъкват на този отговор на SQL Server 2012+, най-лесният начин за постигане на този резултат от автоматично увеличаваща се колона би бил да се създаде SEQUENCE
обект и задайте next value for seq
като колоната по подразбиране.
Алтернативно, или за предишни версии (от 2005 г. нататък), заобикалянето, публикувано в този елемент за свързване, показва напълно поддържан начин за извършване на това без нужда от операции с размер на данни с помощта на ALTER TABLE...SWITCH
. Тук също блогвате за MSDN. Въпреки че кодът за постигане на това не е много прост и има ограничения - като например променяната таблица не може да бъде обект на ограничение за външен ключ.
Примерен код.
Настройте тестова таблица без identity
колона.
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
Променете го, за да има identity
колона (повече или по-малко моментално).
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;
Тествайте резултата.
INSERT INTO dbo.tblFoo (filler,filler2)
OUTPUT inserted.*
VALUES ('foo','bar')
Дава
bar filler filler2
----------- --------- ---------
10001 foo bar
Почистете
DROP TABLE dbo.tblFoo