Ich verwende diesen Code, um die Identität einer Tabelle zurückzusetzen:
DBCC CHECKIDENT('TableName', RESEED, 0)
Dies funktioniert die meiste Zeit einwandfrei. Beim ersten Einfügen füge ich 1 in die ID-Spalte ein. Wenn ich jedoch die Datenbank lösche und neu erstelle (mithilfe von Skripten, die ich geschrieben habe) und dann DBCC CHECKIDENT aufrufe, hat das erste eingefügte Element die ID 0.
Irgendwelche Ideen?
BEARBEITEN: Nach Recherchen stellte ich fest, dass ich die Dokumentation nicht richtig gelesen habe - "Der aktuelle Identitätswert wird auf new_reseed_value gesetzt. Wenn seit der Erstellung keine Zeilen in die Tabelle eingefügt wurden, wird die erste nach dem Ausführen von DBCC CHECKIDENT eingefügte Zeile eingefügt Verwenden Sie new_reseed_value als Identität. Andernfalls wird in der nächsten eingefügten Zeile new_reseed_value + 1 verwendet. "
quelle
Sie haben Recht mit dem, was Sie in der Bearbeitung Ihrer Frage schreiben.
Nach dem Ausführen
DBCC CHECKIDENT('TableName', RESEED, 0)
:- Neu erstellte Tabellen beginnen mit Identität 0
- Vorhandene Tabellen werden mit Identität 1 fortgesetzt
Die Lösung ist im Skript unten, es ist eine Art Poor-Mans-Truncate :)
-- Remove all records from the Table DELETE FROM TableName -- Use sys.identity_columns to see if there was a last known identity value -- for the Table. If there was one, the Table is not new and needs a reset IF EXISTS (SELECT * FROM sys.identity_columns WHERE OBJECT_NAME(OBJECT_ID) = 'TableName' AND last_value IS NOT NULL) DBCC CHECKIDENT (TableName, RESEED, 0);
quelle
object_id
anstelle der VerwendungOBJECT_NAME()
der Tabelle Namen zu sehen:IF EXISTS (SELECT * FROM sys.identity_columns WHERE object_id = OBJECT_ID('Schema.TableName') AND last_value IS NOT NULL
)Ändern Sie die Anweisung in
Dies beginnt bei 2 (oder 1, wenn Sie eine Tabelle neu erstellen), ist jedoch niemals 0.
quelle
Ich habe dies als Experiment durchgeführt, um den Wert auf 0 zurückzusetzen, da meine erste Identitätsspalte 0 sein soll und es funktioniert.
quelle
Es erscheint lächerlich, dass Sie eine Identitätsspalte nicht mit einem einzigen Befehl festlegen / zurücksetzen können, um beide Fälle abzudecken, in denen in die Tabelle Datensätze eingefügt wurden oder nicht. Ich konnte das Verhalten, das ich erlebte, nicht verstehen, bis ich auf SO!
Meine Lösung (hässlich, aber funktioniert) besteht darin, die
sys.identity_columns.last_value
Tabelle explizit zu überprüfen (was Ihnen sagt, ob in die Tabelle Datensätze eingefügt wurden oder nicht) und jeweils den entsprechendenDBCC CHECKIDENT
Befehl aufzurufen . Es ist wie folgt:DECLARE @last_value INT = CONVERT(INT, (SELECT last_value FROM sys.identity_columns WHERE OBJECT_NAME(OBJECT_ID) = 'MyTable')); IF @last_value IS NULL BEGIN -- Table newly created and no rows inserted yet; start the IDs off from 1 DBCC CHECKIDENT ('MyTable', RESEED, 1); END ELSE BEGIN -- Table has rows; ensure the IDs continue from the last ID used DECLARE @lastValUsed INT = (SELECT ISNULL(MAX(ID),0) FROM MyTable); DBCC CHECKIDENT ('MyTable', RESEED, @lastValUsed); END
quelle
Siehe auch hier: http://sqlblog.com/blogs/alexander_kuznetsov/archive/2008/06/26/fun-with-dbcc-chekident.aspx
Dies ist ein dokumentiertes Verhalten. Warum führen Sie CHECKIDENT aus, wenn Sie die Tabelle neu erstellen? In diesem Fall überspringen Sie den Schritt oder verwenden Sie TRUNCATE (wenn Sie keine FK-Beziehungen haben).
quelle
Ich habe dies in SQL verwendet, um IDENTITY auf einen bestimmten Wert zu setzen: -
DECLARE @ID int = 42; DECLARE @TABLENAME varchar(50) = 'tablename' DECLARE @SQL nvarchar(1000) = 'IF EXISTS (SELECT * FROM sys.identity_columns WHERE OBJECT_NAME(OBJECT_ID) = '''+@TABLENAME+''' AND last_value IS NOT NULL) BEGIN DBCC CHECKIDENT('+@TABLENAME+', RESEED,' + CONVERT(VARCHAR(10),@ID-1)+'); END ELSE BEGIN DBCC CHECKIDENT('+@TABLENAME+', RESEED,' + CONVERT(VARCHAR(10),@ID)+'); END'; EXEC (@SQL);
Und dies in C #, um einen bestimmten Wert festzulegen: -
SetIdentity(context, "tablename", 42); . . private static void SetIdentity(DbContext context, string table,int id) { string str = "IF EXISTS (SELECT * FROM sys.identity_columns WHERE OBJECT_NAME(OBJECT_ID) = '" + table + "' AND last_value IS NOT NULL)\nBEGIN\n"; str += "DBCC CHECKIDENT('" + table + "', RESEED," + (id - 1).ToString() + ");\n"; str += "END\nELSE\nBEGIN\n"; str += "DBCC CHECKIDENT('" + table + "', RESEED," + (id).ToString() + ");\n"; str += "END\n"; context.Database.ExecuteSqlCommand(str); }
Dies baut auf den obigen Antworten auf und stellt immer sicher, dass der nächste Wert 42 ist (in diesem Fall).
quelle
Aus Zyphrax 'Antwort entlehnt ...
USE DatabaseName DECLARE @ReseedBit BIT = COALESCE((SELECT SUM(CONVERT(BIGINT, ic.last_value)) FROM sys.identity_columns ic INNER JOIN sys.tables t ON ic.object_id = t.object_id), 0) DECLARE @Reseed INT = CASE WHEN @ReseedBit = 0 THEN 1 WHEN @ReseedBit = 1 THEN 0 END DBCC CHECKIDENT ('dbo.table_name', RESEED, @Reseed);
Vorsichtsmaßnahmen: Dies ist für die Verwendung in Referenzdatenpopulationssituationen vorgesehen, in denen eine Datenbank mit Aufzählungstypdefinitionstabellen initialisiert wird, wobei die ID-Werte in diesen Tabellen immer bei 1 beginnen müssen. Beim ersten Erstellen der Datenbank (z. B. während der SSDT-) DB-Veröffentlichung) @Reseed muss 0 sein, aber wenn Sie die Daten zurücksetzen, dh die Daten entfernen und erneut einfügen, muss @Reseed 1 sein. Dieser Code ist also für die Verwendung in einer gespeicherten Prozedur zum Zurücksetzen der DB-Daten vorgesehen manuell aufgerufen werden, wird aber auch über das Post-Deployment-Skript im SSDT-DB-Projekt aufgerufen. Auf diese Weise werden die Referenzdateneinfügungen nur an einer Stelle definiert, dürfen jedoch nicht nur nach der Bereitstellung während der Veröffentlichung verwendet werden. Sie können auch später verwendet werden (zur Unterstützung von Entwicklern und automatisierten Tests usw.).
quelle
Mach das einfach:
IF EXISTS (SELECT * FROM tablename) BEGIN DELETE from tablename DBCC checkident ('tablename', reseed, 0) END
quelle
USE AdventureWorks2012; GO DBCC CHECKIDENT ('Person.AddressType', RESEED, 0); GO AdventureWorks2012=Your databasename Person.AddressType=Your tablename
quelle