Modification de l'IDENTITY
propriété est vraiment un changement de métadonnées uniquement. Mais pour mettre à jour les métadonnées directement, il faut démarrer l'instance en mode mono-utilisateur et jouer avec certaines colonnes dans sys.syscolpars
et n'est pas documenté/non pris en charge et ce n'est pas quelque chose que je recommanderais ou sur lequel je donnerai des détails supplémentaires.
Pour les personnes rencontrant cette réponse sur SQL Server 2012+, le moyen de loin le plus simple d'obtenir ce résultat d'une colonne à incrémentation automatique serait de créer une SEQUENCE
objet et définissez la next value for seq
comme colonne par défaut.
Alternativement, ou pour les versions précédentes (à partir de 2005), la solution de contournement publiée sur cet élément de connexion montre une manière entièrement prise en charge de le faire sans avoir besoin d'opérations de taille de données à l'aide de ALTER TABLE...SWITCH
. A également blogué sur MSDN ici. Bien que le code pour y parvenir ne soit pas très simple et qu'il existe des restrictions - telles que la table en cours de modification ne peut pas être la cible d'une contrainte de clé étrangère.
Exemple de code.
Configurer une table de test sans identity
colonne.
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
Modifiez-le pour avoir une identity
colonne (plus ou moins instantanée).
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;
Testez le résultat.
INSERT INTO dbo.tblFoo (filler,filler2)
OUTPUT inserted.*
VALUES ('foo','bar')
Donne
bar filler filler2
----------- --------- ---------
10001 foo bar
Nettoyer
DROP TABLE dbo.tblFoo