Réinitialiser l'incrémentation automatique dans SQL Server après la suppression

266

J'ai supprimé certains enregistrements d'une table dans une base de données SQL Server. Maintenant, les ID vont de 101 à 1200. Je veux à nouveau supprimer les enregistrements, mais je veux que les ID reviennent à 102. Existe-t-il un moyen de le faire dans SQL Server?

jumbojs
la source
46
S'il vous plaît, ne dites pas «ne le faites pas» Je déteste quand je demande comment faire quelque chose et tout ce que j'obtiens est de ne pas le faire. Oui, la réinitialisation de l'identité peut entraîner des problèmes de clé étrangère, mais uniquement si vous ne connaissez pas votre base de données et votre programme en conséquence. Il y a de très bonnes raisons de réinitialiser une identité après une suppression programmée - ils sont appelés Auditeurs. Les auditeurs détestent voir les lacunes, alors comblez-les, faites-le de manière contrôlée et assurez-vous que les contraintes de clés étrangères sont maintenues.
6
@spyder, saviez-vous que vous aurez des lacunes si une insertion d'enregistrement est annulée, pas seulement pour la suppression? Vous ne pouvez pas éviter les lacunes avec une incrémentation automatique et il est insensé d'essayer. J'ai travaillé pour une agence d'audit et des auditeurs compétents peuvent leur expliquer cela. De plus, si vous disposez de tables d'audit appropriées, ils peuvent voir ce qui est arrivé à ces enregistrements. Ou s'il ne doit jamais y avoir de lacunes pour des raisons juridiques (il y en a quelques cas), alors seul un développeur incompétent utiliserait l'auto-incrémentation et les auditeurs sont à juste titre contrariés.
HLGEM

Réponses:

457

Exécutez la commande suivante pour réamorcer mytable pour commencer à 1:

DBCC CHECKIDENT (mytable, RESEED, 0)

Lisez à ce sujet dans la documentation en ligne (BOL, aide SQL). Veillez également à ne pas avoir d'enregistrements supérieurs à la valeur de départ que vous définissez.

Robert Wagner
la source
4
... car les identifiants de ces enregistrements seront à nouveau réutilisés avec plaisir, ce qui causera un désordre.
2010 à 10h16
3
En fait, pour démarrer les identifiants à 1, vous devez utiliser 0: DBCC CHECKIDENT (mytable, RESEED, 0)
Ryan Lundy
7
"DBCC CHECKIDENT (nom_table)" définit la graine à l'identité la plus élevée dans la table, que vous n'avez pas à "faire attention"
user1027167
4
@ user1027167 Non, votre réponse n'a pas fonctionné pour moi. Il a continué à incrémenter l'ID le plus élevé qu'il avait enregistré en interne. J'ai dû explicitement utiliser "RESEED, 18" dans mon cas pour obtenir "19" comme ID suivant. Sans cela, il continuait joyeusement à augmenter sur "29".
Matthis Kohli
DBCC CHECKIDENT (nom_table) ne modifie la valeur de départ que si la valeur d'identité est inférieure à la valeur maximale dans la colonne. Donc, si la valeur d'identité est déjà plus grande comme dans le cas @MatthisKohli, le réamorçage explicite doit être appelé.
Martheen
82
DBCC CHECKIDENT('databasename.dbo.tablename', RESEED, number)

si nombre = 0 alors dans l'insertion suivante le champ d'incrémentation automatique contiendra la valeur 1

si nombre = 101, dans la prochaine insertion, le champ d'incrémentation automatique contiendra la valeur 102


Quelques informations supplémentaires ... Peut vous être utile

Avant de donner l'incrémentation automatique numberdans la requête ci-dessus, vous devez vous assurer que la colonne d'incrémentation automatique de votre table existante contient des valeurs inférieures number.

Pour obtenir la valeur maximale d'une colonne (nom_colonne) à partir d'une table (table1), vous pouvez utiliser la requête suivante

 SELECT MAX(column_name) FROM table1
Fathah Rehman P
la source
37

semi-idiot-preuve:

declare @max int;  
select @max = max(key) from table;  
dbcc checkident(table,reseed,@max)

http://sqlserverplanet.com/tsql/using-dbcc-checkident-to-reseed-a-table-after-delete

user423430
la source
1
"DBCC CHECKIDENT (nom_table)" fait de même (possible sans conditions de course)
user1027167
2
@ user1027167 Les documents indiquent «si la valeur d'identité actuelle d'une table est inférieure à la valeur d'identité maximale stockée dans la colonne d'identité»; qui ne couvre pas le nettoyage après la suppression des données (réutiliser les identifiants - souvent une mauvaise idée). Vérifié sur SQL 2008
user423430
1
La meilleure réponse systématique et automatique. Bravo!
Mehdi Khademloo
11

Si vous utilisez MySQL, essayez ceci:

ALTER TABLE tablename AUTO_INCREMENT = 1
xaa
la source
3
Ceci est une réponse pour MySQL. OP pose des questions sur MSSQL.
réformé le
la question concerne MS SQL Server
Saher Ahwal
6

Supprimez et réamorcez toutes les tables d'une base de données.

    USE [DatabaseName]
    EXEC sp_msforeachtable "ALTER TABLE ? NOCHECK CONSTRAINT all"       -- Disable All the constraints
    EXEC sp_MSForEachTable "DELETE FROM ?"    -- Delete All the Table data
    Exec sp_MSforeachtable 'DBCC CHECKIDENT(''?'', RESEED, 0)' -- Reseed All the table to 0
    Exec sp_msforeachtable "ALTER TABLE ? WITH CHECK CHECK CONSTRAINT all"  -- Enable All  the constraints back

-- You may ignore the errors that shows the table without Auto increment field.
BMG
la source
6

Je l'ai compris. Ses:

 DBCC CHECKIDENT ('tablename', RESEED, newseed)
jumbojs
la source
4

Sur la base de la réponse acceptée, pour ceux qui ont rencontré un problème similaire, avec une qualification de schéma complète:

( [MyDataBase].[MySchemaName].[MyTable]) ... entraîne une erreur, vous devez être dans le contexte de cette BD

Autrement dit, ce qui suit générera une erreur:

DBCC CHECKIDENT ([MyDataBase].[MySchemaName].[MyTable], RESEED, 0)

Ajoutez plutôt le nom de table complet avec des guillemets simples:

DBCC CHECKIDENT ('[MyDataBase].[MySchemaName].[MyTable]', RESEED, 0)
user919426
la source
4

Plusieurs réponses recommandent d'utiliser une déclaration comme celle-ci:

DBCC CHECKIDENT (mytable, RESEED, 0)

Mais l'OP a dit "supprimé certains enregistrements", qui ne sont peut-être pas tous, donc une valeur de 0 n'est pas toujours la bonne. Une autre réponse a suggéré de trouver automatiquement la valeur actuelle maximale et de réamorcer celle-ci, mais cela pose problème s'il n'y a aucun enregistrement dans la table, et donc max () renverra NULL. Un commentaire suggéré d'utiliser simplement

DBCC CHECKIDENT (mytable)

pour réinitialiser la valeur, mais un autre commentaire a correctement déclaré que cela ne fait qu'augmenter la valeur au maximum déjà dans le tableau; cela ne réduira pas la valeur si elle est déjà supérieure au maximum dans le tableau, ce que l'OP voulait faire.

Une meilleure solution combine ces idées. Le premier CHECKIDENT réinitialise la valeur à 0 et le second la réinitialise à la valeur la plus élevée actuellement dans la table, au cas où il y aurait des enregistrements dans la table:

DBCC CHECKIDENT (mytable, RESEED, 0)
DBCC CHECKIDENT (mytable)

Comme plusieurs commentaires l'ont indiqué, assurez-vous qu'il n'y a pas de clés étrangères dans d'autres tables pointant vers les enregistrements supprimés. Sinon, ces clés étrangères pointeront vers les enregistrements que vous créez après avoir réamorcé la table, ce qui n'est certainement pas ce que vous aviez en tête.

Michael Rodby
la source
4

Je veux ajouter cette réponse car l' DBCC CHECKIDENTapproche -produira des problèmes lorsque vous utilisez des schémas pour les tables. Utilisez ceci pour être sûr:

DECLARE @Table AS NVARCHAR(500) = 'myschema.mytable';
DBCC CHECKIDENT (@Table, RESEED, 0);

Si vous souhaitez vérifier le succès de l'opération, utilisez

SELECT IDENT_CURRENT(@Table);

qui devrait sortir 0dans l'exemple ci-dessus.

Alexander Schmidt
la source
1

Vous ne voulez pas faire cela en général. Le réensemencement peut créer des problèmes d'intégrité des données. Il n'est vraiment destiné qu'à être utilisé sur des systèmes de développement où vous supprimez toutes les données de test et recommencez. Il ne doit pas être utilisé sur un système de production au cas où tous les enregistrements associés n'auraient pas été supprimés (pas toutes les tables qui devraient être dans une relation de clé étrangère!). Vous pouvez créer un gâchis en faisant cela et surtout si vous voulez le faire régulièrement après chaque suppression. C'est une mauvaise idée de s'inquiéter des lacunes dans les valeurs de votre champ d'identité.

HLGEM
la source
6
Je ne l'utiliserai pas tout le temps et ce n'était que sur une base de données de test.
jumbojs
0

Et ça?

ALTER TABLE `table_name`
  MODIFY `id` int(12) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=0;

Il s'agit d'un moyen rapide et simple de modifier l'incrémentation automatique sur 0 ou sur le nombre souhaité. J'ai compris cela en exportant une base de données et en lisant le code moi-même.

Vous pouvez également l'écrire comme ceci pour en faire une solution monoligne:

ALTER TABLE `table_name` MODIFY `id` int(12) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=0;
Victor Resnov
la source
1
Merci pour cet extrait de code, qui pourrait fournir une aide limitée et immédiate. Une explication appropriée améliorerait considérablement sa valeur à long terme en montrant pourquoi c'est une bonne solution au problème, et la rendrait plus utile aux futurs lecteurs avec d'autres questions similaires. Veuillez modifier votre réponse pour ajouter des explications, y compris les hypothèses que vous avez faites.
Au revoir StackExchange