2009-02-04 8 views
199

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 supprimer les enregistrements à nouveau, mais je veux que les ID reviennent à 102. Existe-t-il un moyen de le faire dans SQL Server?Réinitialiser l'incrémentation automatique dans SQL Server après la suppression

+33

Veuillez ne pas dire "Ne pas le faire". Je déteste quand je demande comment faire quelque chose et tout ce que je reçois n'est pas. 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 que vous programmez en conséquence. Il existe de très bonnes raisons de réinitialiser une identité après une suppression détaillée - ils sont appelés Auditeurs. Les vérificateurs détestent voir les lacunes afin de les remplir, de le faire d'une manière contrôlée et de s'assurer 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 non seulement pour la suppression? Vous ne pouvez pas éviter les lacunes avec un autoincrement et il est stupide d'essayer. J'ai travaillé pour une agence d'audit et les auditeurs compétents peuvent leur expliquer cela. De plus, si vous avez des tables d'audit appropriées, ils peuvent voir ce qu'il est advenu de ces enregistrements. Ou s'il ne doit y avoir aucune lacune pour des raisons légales (il y a quelques cas de cela), alors seulement un développeur incompétent utiliserait un auto-incrément et les auditeurs sont à juste titre contrariés. – HLGEM

Répondre

348

Exécutez la commande suivante pour réensemencer matable pour commencer à 1:

DBCC CHECKIDENT (mytable, RESEED, 0) 

lu dans les livres en ligne (BOL, aide SQL). Veillez également à ne pas avoir d'enregistrements plus élevés que la graine que vous définissez.

+3

... parce que les identifiants de ces enregistrements seront heureusement réutilisés, causant un mauvais désordre. – nalply

+0

que diriez-vous d'un zéro? – Joset

+3

En fait, afin de démarrer les ID à 1, vous devez utiliser 0: 'DBCC CHECKIDENT (mytable, RESEED, 0)' –

3

Je l'ai compris. C'est:

DBCC CHECKIDENT ('tablename', RESEED, newseed) 
2

Vous ne voulez pas faire cela en général. La régénération peut créer des problèmes d'intégrité des données. C'est vraiment seulement pour une utilisation sur les systèmes de développement où vous êtes en train d'effacer toutes les données de test et de recommencer. Il ne devrait pas être utilisé sur un système de production au cas où tous les enregistrements associés n'auraient pas été supprimés (toutes les tables qui devraient être dans une relation de clé étrangère ne le sont pas!). Vous pouvez créer un désordre 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 vos valeurs de champ d'identité.

+6

Je ne l'utiliserai pas tout le temps et ce n'est que sur un test db. – jumbojs

29

semi-con-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

+1

"DBCC CHECKIDENT (nom_table)" fait la même chose (possible sans conditions de concurrence) – user1027167

+2

@ user1027167 Les docs 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é'; cela ne couvre pas le nettoyage après la suppression des données (réutilisation des identifiants - souvent une mauvaise idée). Vérifié le SQL 2008 – user423430

+1

La meilleure réponse systématique et automatique. Bravo! –

63
DBCC CHECKIDENT('databasename.dbo.tablename', RESEED, number) 

si le nombre = 0 puis dans le prochain insérer le champ d'incrémentation automatique contiendra la valeur 1

si le nombre = 101 puis dans l'encart suivant, le champ d'incrémentation automatique contiendra la valeur 102


Quelques infos supplémentaires ... Peut être utile pour vous

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

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

SELECT MAX(column_name) FROM table1 
7

Essayez ceci:

ALTER TABLE tablename AUTO_INCREMENT = 1 
+4

Si je ne me trompe pas, la réponse est bonne pour mysql. – Carol

+1

Ceci est une réponse pour MySQL. OP pose des questions sur MSSQL. – reformed

5

Supprimer et Réensemencer toutes les tables dans 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. 
4

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

([MyDataBase].[MySchemaName].[MyTable]) ...provoque une erreur, vous devez être dans le contexte de ce DB

C'est, ce qui suit renvoie une erreur:

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

Entourez le nom de table entièrement qualifié avec des guillemets simples au lieu:

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

Plusieurs réponses vous recommandons d'utiliser un quelque chose de déclaration comme ceci:

DBCC CHECKIDENT (mytable, RESEED, 0) 

Mais le PO 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 suggérait de trouver automatiquement la valeur actuelle maximum et de la ré-initialiser à celle-là, mais cela se complique s'il n'y a pas d'enregistrements dans la table, et donc max() retournera NULL. Un commentaire a suggéré d'utiliser simplement

DBCC CHECKIDENT (mytable) 

pour réinitialiser la valeur, mais un autre commentaire a déclaré à juste titre que cela ne fait qu'accroître la valeur au maximum déjà dans la table; cela ne réduira pas la valeur si elle est déjà supérieure au maximum dans la table, ce que le PO voulait faire.

Une meilleure solution combine ces idées. La première CHECKIDENT remet à zéro la valeur à 0, et le second remet à zéro à la valeur la plus élevée actuellement dans le tableau, au cas où il y a des enregistrements de la table:

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

ont indiqué des commentaires Comme plusieurs, assurez-vous qu'il n'y a pas 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éerez après avoir réensemencé la table, ce qui n'est certainement pas ce que vous aviez en tête.

0

Je souhaite ajouter cette réponse car l'approche DBCC CHECKIDENT génère des problèmes lorsque vous utilisez des schémas pour des tables. Utilisez cette option pour être sûr:

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

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

SELECT IDENT_CURRENT(@Table); 

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

Questions connexes