Alterando a
IDENTITY
é realmente uma mudança apenas de metadados. Mas para atualizar os metadados diretamente requer iniciar a instância no modo de usuário único e mexer em algumas colunas em sys.syscolpars
e não é documentado/sem suporte e não é algo que eu recomendaria ou forneceria detalhes adicionais. Para as pessoas que se deparam com esta resposta no SQL Server 2012+, de longe, a maneira mais fácil de obter esse resultado de uma coluna de incremento automático seria criar uma
SEQUENCE
object e defina o next value for seq
como o padrão da coluna. Alternativamente, ou para versões anteriores (de 2005 em diante), a solução postada neste item de conexão mostra uma maneira totalmente suportada de fazer isso sem a necessidade de operações de tamanho de dados usando
ALTER TABLE...SWITCH
. Também blogou sobre no MSDN aqui. Embora o código para conseguir isso não seja muito simples e haja restrições - como a tabela que está sendo alterada não pode ser alvo de uma restrição de chave estrangeira. Código de exemplo.
Configurar tabela de teste sem identity
coluna.
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
Altere-o para ter uma identity
coluna (mais ou menos instantânea).
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;
Teste o resultado.
INSERT INTO dbo.tblFoo (filler,filler2)
OUTPUT inserted.*
VALUES ('foo','bar')
Dá
bar filler filler2
----------- --------- ---------
10001 foo bar
Limpeza
DROP TABLE dbo.tblFoo