Setzen Sie den Identitäts-Seed zurück, nachdem Sie Datensätze in SQL Server gelöscht haben

682

Ich habe Datensätze in eine SQL Server-Datenbanktabelle eingefügt. In der Tabelle wurde ein Primärschlüssel definiert, und der Startwert für die automatische Inkrementierung der Identität wird auf "Ja" gesetzt. Dies erfolgt hauptsächlich, weil in SQL Azure für jede Tabelle ein Primärschlüssel und eine Identität definiert sein müssen.

Da ich jedoch einige Datensätze aus der Tabelle löschen muss, wird der Identitätsstartwert für diese Tabellen gestört und die Indexspalte (die automatisch mit einem Inkrement von 1 generiert wird) wird gestört.

Wie kann ich die Identitätsspalte zurücksetzen, nachdem ich die Datensätze gelöscht habe, sodass die Reihenfolge der Spalte in aufsteigender numerischer Reihenfolge erfolgt?

Die Identitätsspalte wird an keiner Stelle in der Datenbank als Fremdschlüssel verwendet.

Xorpower
quelle
4
"in SQL Azure" - "Jede Tabelle muss einen Primärschlüssel haben" - true - "und Identity Defined" - false. Identität und Primärschlüssel sind orthogonale Konzepte. Eine Identitätsspalte muss nicht die PK einer Tabelle sein. Ein Primärschlüssel muss keine Identitätsspalte sein.
Damien_The_Unbeliever
OK. Mein Konzept könnte falsch sein. Aber jetzt habe ich die Tabellenstruktur mit PK und Identity Seed definiert. Wenn ich einige Zeilen löschen muss, wie könnte ich Identity Seed in einer korrekten numerischen aufsteigenden Reihenfolge
zurücksetzen
29
Ich würde immer argumentieren, dass Sie sie missbrauchen, wenn Sie sich für die tatsächlichen numerischen Werte interessieren, die in einer Identitätsspalte generiert werden. Alles, was Sie bei einer Identitätsspalte beachten sollten, ist, dass sie automatisch eindeutige Werte generiert (yay!) Und dass Sie diese Werte in einer numerischen Spalte speichern können (dieses Bit ist nur relevant, um Spalten zu deklarieren, die diese Werte enthalten sollen). Sie sollten sie niemandem zeigen, daher sollte es keine Rolle spielen, welche Werte sie annehmen.
Damien_The_Unbeliever
Sie können Dbcc Check Identify wie andere erwähnt verwenden, aber bitte beachten Sie, dass der Primärschlüssel für SQL
DB

Antworten:

1099

Der DBCC CHECKIDENTVerwaltungsbefehl wird verwendet, um den Identitätszähler zurückzusetzen. Die Befehlssyntax lautet:

DBCC CHECKIDENT (table_name [, { NORESEED | { RESEED [, new_reseed_value ]}}])
[ WITH NO_INFOMSGS ]

Beispiel:

DBCC CHECKIDENT ('[TestTable]', RESEED, 0);
GO

Es wurde in früheren Versionen der Azure SQL-Datenbank nicht unterstützt, wird aber jetzt unterstützt.


Beachten Sie, dass das new_reseed_valueArgument je nach Dokumentation in den SQL Server-Versionen unterschiedlich ist :

Wenn Zeilen in der Tabelle vorhanden sind, wird die nächste Zeile mit dem Wert new_reseed_value eingefügt . In Version SQL Server 2008 R2 und früheren Versionen verwendet die nächste eingefügte Zeile new_reseed_value + den aktuellen Inkrementwert.

Aber ich diese Informationen irreführend finden (einfach falsch tatsächlich) , weil beobachtet Verhalten zeigt an, dass mindestens SQL Server 2012 ist nach wie vor verwendet new_reseed_value + die aktuelle Inkrementwert Logik. Microsoft widerspricht sogar seiner eigenen Example Cauf derselben Seite:

C. Erzwingen des aktuellen Identitätswerts auf einen neuen Wert

Im folgenden Beispiel wird der aktuelle Identitätswert in der AddressTypeID-Spalte in der AddressType-Tabelle auf den Wert 10 gesetzt. Da in der Tabelle vorhandene Zeilen vorhanden sind, wird in der nächsten eingefügten Zeile 11 als Wert verwendet, dh der neue aktuelle Inkrementwert, für den definiert wurde der Spaltenwert plus 1.

USE AdventureWorks2012;  
GO  
DBCC CHECKIDENT ('Person.AddressType', RESEED, 10);  
GO

Dies alles lässt jedoch eine Option für unterschiedliches Verhalten bei neueren SQL Server-Versionen. Ich denke, der einzige Weg, um sicher zu sein, bis Microsoft die Dinge in seiner eigenen Dokumentation klärt, besteht darin, vor der Verwendung tatsächliche Tests durchzuführen.

Petr Abdulin
quelle
23
Syntax wäre ... DBCC CHECKIDENT ('[TestTable]', RESEED, 0) GO
Biki
2
Es scheint, dass DBCC CHECKIDENTdies ab der kommenden Version (V12 / Sterling) unterstützt wird: azure.microsoft.com/en-us/documentation/articles/… Für diese spezielle Situation würde ich TRUNCATE TABLE dennoch empfehlen :)
Solomon Rutzky
1
Es hat bei mir nicht funktioniert, bis das "GO" in einer anderen Zeile war.
Mrówa
1
Die Syntax wird aufgrund des Schlüsselworts GO in derselben Zeile markiert. Ich weiß nicht warum. Können Sie es eine Linie nach unten verschieben. Ich habe diese Zeile 50 Mal kopiert und eingefügt und jetzt muss ich zurückgehen und sie reparieren.
AnotherDeveloper
4
Hat perfekt für mich funktioniert. Es ist erwähnenswert, dass beim erneuten Seeding einer Tabelle, wenn Sie erneut säen möchten, sodass Ihr erster Datensatz ID 1 ist, der Befehl reseed erneut auf 0 gesetzt werden muss, damit der nächste Datensatz ID 1 ist.
Mike Upjohn
215
DBCC CHECKIDENT ('TestTable', RESEED, 0)
GO

Wobei 0 der identityStartwert ist

Anil Shah
quelle
15
Wenn die Tabelle leer ist, z. B. wenn Sie gerade aufgerufen haben TRUNCATE, sollte der neue Startwert der Wert sein, der bei der nächsten Verwendung verwendet werden soll (dh 1 nicht 0). Wenn die Tabelle nicht leer ist, wird die verwendet new_reseed_value + 1. MSDN
kjbartel
2
@kjbartel, Anil und andere: Es ist nicht so einfach wie "wenn die Tabelle leer ist". In der Dokumentation fehlte der Fall, wenn die Tabelle aufgrund von DELETEnicht leer TRUNCATEist new_reseed+value + 1. In diesem Fall ist dies auch der Fall . Ich habe einen Beitrag darüber geschrieben, in dem das tatsächliche Verhalten anhand einiger Tests gezeigt und das aktuelle Dokument aktualisiert wurde (jetzt, da es auf GitHub verfügbar ist ): Wie funktioniert der DBCC-CHECKIDENT beim Zurücksetzen des Identitäts-Seeds (RESEED) wirklich? .
Solomon Rutzky
87

Es sollte beachtet werden, dass, wenn alle Daten über die DELETE(dh keine WHEREKlausel) aus der Tabelle entfernt werden , solange a) Berechtigungen dies zulassen und b) keine FKs vorhanden sind, die auf die Tabelle verweisen (was zu sein scheint) der Fall hier) TRUNCATE TABLEwäre die Verwendung bevorzugt, da dies effizienter ist DELETE und gleichzeitig den IDENTITYSamen zurücksetzt . Die folgenden Details stammen von der MSDN-Seite für TRUNCATE TABLE :

Gegenüber der DELETE-Anweisung bietet TRUNCATE TABLE folgende Vorteile:

  • Es wird weniger Transaktionsprotokollplatz verwendet.

    Die DELETE-Anweisung entfernt Zeilen nacheinander und zeichnet für jede gelöschte Zeile einen Eintrag im Transaktionsprotokoll auf. TRUNCATE TABLE entfernt die Daten, indem die zum Speichern der Tabellendaten verwendeten Datenseiten freigegeben werden, und zeichnet nur die Seitenfreigaben im Transaktionsprotokoll auf.

  • In der Regel werden weniger Schlösser verwendet.

    Wenn die DELETE-Anweisung mit einer Zeilensperre ausgeführt wird, wird jede Zeile in der Tabelle zum Löschen gesperrt. TRUNCATE TABLE sperrt immer die Tabelle (einschließlich einer Schemasperre (SCH-M)) und die Seite, jedoch nicht jede Zeile.

  • In der Tabelle verbleiben ausnahmslos keine Seiten.

    Nachdem eine DELETE-Anweisung ausgeführt wurde, kann die Tabelle noch leere Seiten enthalten. Beispielsweise können leere Seiten in einem Heap nicht ohne mindestens eine exklusive Tabellensperre (LCK_M_X) freigegeben werden. Wenn beim Löschvorgang keine Tabellensperre verwendet wird, enthält die Tabelle (Heap) viele leere Seiten. Bei Indizes kann der Löschvorgang leere Seiten zurücklassen, obwohl diese Seiten durch einen Hintergrundbereinigungsprozess schnell freigegeben werden.

Wenn die Tabelle eine Identitätsspalte enthält, wird der Zähler für diese Spalte auf den für die Spalte definierten Startwert zurückgesetzt. Wenn kein Startwert definiert wurde, wird der Standardwert 1 verwendet. Verwenden Sie stattdessen DELETE, um den Identitätszähler beizubehalten.

Also folgendes:

DELETE FROM [MyTable];
DBCC CHECKIDENT ('[MyTable]', RESEED, 0);

Wird einfach:

TRUNCATE TABLE [MyTable];

TRUNCATE TABLEWeitere Informationen zu Einschränkungen usw. finden Sie in der Dokumentation (oben verlinkt).

Solomon Rutzky
quelle
8
Dies ist unter den richtigen Umständen zwar effizienter, aber nicht immer eine Option. Das Abschneiden wird nicht für eine Tabelle ausgeführt, für die ein FK definiert ist. Selbst wenn keine abhängigen Datensätze vorhanden sind, schlägt das Abschneiden fehl, wenn die Einschränkung vorhanden ist. Auch das Abschneiden erfordert ALTER-Berechtigungen, wobei Löschen nur LÖSCHEN erfordert.
Rozwel
3
@Rozwel Stimmt, aber ich hatte meine Antwort bereits qualifiziert und festgestellt, dass die richtigen Berechtigungen vorhanden sein müssen. In der Frage heißt es auch ausdrücklich, dass es keine FKs gibt. Aus Gründen der Übersichtlichkeit habe ich jedoch aktualisiert, um die Einschränkung "no FK" anzugeben. Vielen Dank für den Hinweis.
Solomon Rutzky
1
Das einzige Problem ist, dass jeder FK das Abschneiden blockiert. Es ist möglich (wenn auch ungewöhnlich), eine FK gegen eine eindeutige Einschränkung zu haben, die nicht Teil der PK- oder Identitätsspalten ist.
Rozwel
1
@Rozwel Wieder wahr, aber es scheint vernünftig, von der Frage anzunehmen, dass es keine eindeutigen Einschränkungen gibt, da die PK nur existiert, weil das OP (richtig oder nicht) versteht, dass sie von der Azure SQL-Datenbank benötigt wird. Unabhängig davon bin ich alle dafür, Mehrdeutigkeiten zu reduzieren, also habe ich erneut aktualisiert. Vielen Dank.
Solomon Rutzky
Es ist nicht allzu ungewöhnlich, einen Fremdschlüssel auf einem Tisch zu haben, und das Vorhandensein eines beliebigen Fremdschlüssels verbietet TRUNCATE TABLE. Ich habe dies heute auf die harte Tour entdeckt, als ich versuchte, TRUNCATE TABLE für eine Tabelle auszuführen, die einen Fremdschlüssel enthält, der für zwei andere Spalten in der Tabelle und einen eindeutigen Index in der Fremdtabelle erzwungen wird.
David A. Gray
83

Obwohl die meisten Antworten RESEED auf 0 vorschlagen, müssen wir oft nur auf die nächste verfügbare ID zurücksetzen

declare @max int
select @max=max([Id])from [TestTable]
if @max IS NULL   //check when max is returned as null
  SET @max = 0
DBCC CHECKIDENT ('[TestTable]', RESEED,@max)

Dadurch wird die Tabelle überprüft und auf die nächste ID zurückgesetzt.

Atal Kishore
quelle
2
Dies ist die einzige Antwort, die 100% der Zeit funktioniert
Reversed Engineer
3
Ein bisschen kürzer:declare @max int select @max=ISNULL(max([Id]),0) from [TestTable]; DBCC CHECKIDENT ('[TestTable]', RESEED, @max );
Guillermo Prandi
61

Ich habe versucht zu @anil shahsantworten und es hat die Identität zurückgesetzt. Aber als eine neue Zeile eingefügt wurde, bekam sie die identity = 2. Also habe ich stattdessen die Syntax geändert in:

DELETE FROM [TestTable]

DBCC CHECKIDENT ('[TestTable]', RESEED, 0)
GO

Dann erhält die erste Zeile die Identität = 1.

Mikael Engver
quelle
16

Obwohl die meisten Antworten sind darauf hindeutet , RESEEDzu 0, und während einige dies als Fehler für siehe TRUNCATEDTabellen, hat Microsoft eine Lösung, umfasst nicht dieID

DBCC CHECKIDENT ('[TestTable]', RESEED)

Dadurch wird die Tabelle überprüft und zum nächsten zurückgesetzt ID. Dies ist seit MS SQL 2005 bis heute verfügbar.

https://msdn.microsoft.com/en-us/library/ms176057.aspx

RealSollyM
quelle
1
Das stimmt leider nicht. Habe das gerade für MS SQL 2014 Server überprüft.
Alehro
1
Eigentlich gilt das für SQL 2014. Ich habe es gerade getestet und es hat bei mir funktioniert.
Daniel Dyson
2
Dies funktioniert in SQL 2012 inkonsistent für mich. Manchmal wird der nächste verfügbare verwendet, wie ich es erwartet hätte, manchmal scheint es, als würde ein alter Wert aus der Tabelle hängen bleiben. Die Angabe des Samens funktioniert immer.
Dan Field
Funktioniert bei SQL 2016 nicht für mich - es lässt nur den Identitäts-Seed unverändert. Es hat vielleicht einmal richtig für mich funktioniert, aber es könnte auch mein Fingerproblem gewesen sein. Kann es nicht wieder zum Laufen bringen
Reversed Engineer
Die Meldung zeigt Erfolg an Checking identity information: current identity value '[incorrect seed]', current column value '[correct seed]'., aber bei neuen Einfügungen wird immer noch der falsche Startwert verwendet.
Denziloe
7

Das Ausgeben von 2 Befehlen kann den Trick machen

DBCC CHECKIDENT ('[TestTable]', RESEED,0)
DBCC CHECKIDENT ('[TestTable]', RESEED)

Der erste setzt die Identität auf Null zurück und der nächste setzt sie auf den nächsten verfügbaren Wert - jacob

Jacob
quelle
2
DBCC CHECKIDENT ('[TestTable]', RESEED) setzt nicht auf den nächsten verfügbaren Wert
Atal Kishore
Dies ist die Methode, die von RedGate Data Compare verwendet wird, wenn die Option "Identitätsspalten neu festlegen" aktiviert ist. Ich habe es ausgiebig getestet (ich meine in SQL-Code, nicht im RedGate-Tool) und es funktioniert zuverlässig. (Ich habe keine Beziehung zu RedGate, außer gelegentlich Benutzer ihrer Testversionen zu sein.)
Reversed Engineer
6

@Jacob

DBCC CHECKIDENT ('[TestTable]', RESEED,0)
DBCC CHECKIDENT ('[TestTable]', RESEED)

Bei mir musste ich nur alle Einträge aus der Tabelle löschen und nach dem Löschen die obigen Einträge an einem Triggerpunkt hinzufügen. Jetzt, wenn ich einen Eintrag lösche, wird von dort genommen.

Epos
quelle
DBCC CHECKIDENT ist erst nach dem Löschen funktionsfähig. Sie können auch "Abschneiden" verwenden. Wenn Sie jedoch den Rest der Daten benötigen, verwenden Sie diese nicht. Auch "Abschneiden" gibt keine Datensatzanzahl der gelöschten Datensätze an.
user763539
6

Truncate Tabelle wird bevorzugt, da sie die Datensätze löscht, den Zähler zurücksetzt und den Speicherplatz zurückfordert.

Deleteund CheckIdentsollte nur verwendet werden, wenn Fremdschlüssel das Abschneiden verhindern.

Dyna Dave
quelle
5

Identitätsspalte mit neuer ID zurücksetzen ...

DECLARE @MAX INT
SELECT @MAX=ISNULL(MAX(Id),0) FROM [TestTable]

DBCC CHECKIDENT ('[TestTable]', RESEED,@MAX)
Mukesh Pandey
quelle
4

Dies ist eine häufige Frage und die Antwort ist immer dieselbe: Tu es nicht. Identitätswerte sollten als willkürlich behandelt werden und als solche gibt es keine "richtige" Reihenfolge.

Ben Thul
quelle
15
Das gilt für eine Produktionsumgebung, aber während der Entwicklung möchte ich daran denken, dass bestimmte Entitäten eine bestimmte ID haben, die aus einem Seeding-Skript ausgefüllt wird. Dies erleichtert die Navigation durch die Datenbank während der Entwicklung erheblich.
Francois Botha
7
Antworten wie diese sind vollständig theoretisch und entsprechen selten den Anforderungen der realen Welt. Wie wäre es, anstatt Menschen mit Ihrem Dogma einer Gehirnwäsche zu unterziehen, die OP-Frage zu beantworten ...
Serj Sagan
1
Coole Geschichte, Bro. Meine Behauptung lautet: Wenn Sie den Wert für eine Spalte angeben möchten, wählen Sie keine Eigenschaft in der Spalte aus, die dies erschwert. Der Codegeruch lautet wie folgt: Wenn Sie jedes Mal, wenn Sie einen Datensatz in eine Tabelle einfügen, einen Wert für die Identitätsspalte angeben, haben Sie keine Identitätsspalte. Der springende Punkt bei der Identität ist, dass der Server einen Wert für Sie erstellt. Wenn Sie also diese Zeit überschreiben, haben Sie nichts für Kosten ungleich Null gewonnen. Auch gute Arbeit am Ad-Hominem-Argument.
Ben Thul
5
Ich stimme Ihrer Behauptung mit Sicherheit zu. In Bezug auf den Nennwert macht das OP es sicherlich falsch, aber vielleicht gibt es eine tiefere Notwendigkeit, die in dem Beitrag nicht angegeben wurde, dass das OP nicht für relevant hielt, um seine Frage zu beantworten. Beantworten Sie daher die Frage und geben Sie als Teil der Antwort Ratschläge zu "Do's and Don'ts". Übrigens habe ich deinen Charakter nie angegriffen ... ad hominem bedeutet, ich habe dich dumm genannt oder so ...
Serj Sagan
1
Obwohl dies in den meisten Fällen sicherlich zutrifft, gibt es Umstände, unter denen es legitim ist, eine Tabelle neu zu erstellen. Zum Beispiel arbeite ich an einem Greenfield-Projekt, das an einem Punkt beginnen muss, der bestimmte Zeilen im Vorgänger berücksichtigt, den es ersetzt. Nachsaaten während der Entwicklung ist ein legitimer Anwendungsfall, IMO.
David A. Gray
3

Führen Sie dieses Skript aus, um die Identitätsspalte zurückzusetzen. Sie müssen zwei Änderungen vornehmen. Ersetzen Sie tableXYZ durch die Tabelle, die Sie aktualisieren möchten. Außerdem muss der Name der Identitätsspalte aus der temporären Tabelle entfernt werden. Dies war in einer Tabelle mit 35.000 Zeilen und 3 Spalten sofort der Fall. Sichern Sie die Tabelle und versuchen Sie dies zunächst in einer Testumgebung.


select * 
into #temp
From tableXYZ

set identity_insert tableXYZ ON

truncate table tableXYZ

alter table #temp drop column (nameOfIdentityColumn)

set identity_insert tableXYZ OFF

insert into tableXYZ
select * from #temp
Matthew Baic
quelle
3
Dies ist nicht ganz richtig: SET IDENTITY_INSERT befindet sich am falschen Ort. Es geht nicht um das TRUNCATE, es geht um das INSERT INTO (daher das identity_ INSERT ). Dies darf auch nur verwendet werden, wenn Daten aufbewahrt werden müssen, da es sonst sehr ineffizient ist, wenn nur die einzelne TRUNCATE-Anweisung ausgeführt wird.
Solomon Rutzky
1
DBCC CHECKIDENT (<TableName>, reseed, 0)

Dadurch wird der aktuelle Identitätswert auf 0 gesetzt.

Beim Einfügen des nächsten Werts wird der Identitätswert auf 1 erhöht.

Bimzee
quelle
1

Verwenden Sie diese gespeicherte Prozedur:

IF (object_id('[dbo].[pResetIdentityField]') IS NULL)
  BEGIN
    EXEC('CREATE PROCEDURE [dbo].[pResetIdentityField] AS SELECT 1 FROM DUMMY');
  END
GO

SET  ANSI_NULLS ON
GO
SET  QUOTED_IDENTIFIER ON
GO

ALTER PROCEDURE [dbo].[pResetIdentityField]
  @pSchemaName NVARCHAR(1000)
, @pTableName NVARCHAR(1000) AS
DECLARE @max   INT;
DECLARE @fullTableName   NVARCHAR(2000) = @pSchemaName + '.' + @pTableName;

DECLARE @identityColumn   NVARCHAR(1000);

SELECT @identityColumn = c.[name]
FROM sys.tables t
     INNER JOIN sys.schemas s ON t.[schema_id] = s.[schema_id]
     INNER JOIN sys.columns c ON c.[object_id] = t.[object_id]
WHERE     c.is_identity = 1
      AND t.name = @pTableName
      AND s.[name] = @pSchemaName

IF @identityColumn IS NULL
  BEGIN
    RAISERROR(
      'One of the following is true: 1. the table you specified doesn''t have an identity field, 2. you specified an invalid schema, 3. you specified an invalid table'
    , 16
    , 1);
    RETURN;
  END;

DECLARE @sqlString   NVARCHAR(MAX) = N'SELECT @maxOut = max(' + @identityColumn + ') FROM ' + @fullTableName;

EXECUTE sp_executesql @stmt = @sqlString, @params = N'@maxOut int OUTPUT', @maxOut = @max OUTPUT

IF @max IS NULL
  SET @max = 0

print(@max)

DBCC CHECKIDENT (@fullTableName, RESEED, @max)
go

--exec pResetIdentityField 'dbo', 'Table'

Ich überlege nur meine Antwort. Ich bin auf ein seltsames Verhalten in SQL Server 2008 R2 gestoßen, das Sie beachten sollten.

drop table test01

create table test01 (Id int identity(1,1), descr nvarchar(10))

execute pResetIdentityField 'dbo', 'test01'

insert into test01 (descr) values('Item 1')

select * from test01

delete from test01

execute pResetIdentityField 'dbo', 'test01'

insert into test01 (descr) values('Item 1')

select * from test01

Die erste Auswahl erzeugt 0, Item 1.

Der zweite produziert 1, Item 1. Wenn Sie den Reset direkt nach dem Erstellen der Tabelle ausführen, ist der nächste Wert 0. Ehrlich gesagt bin ich nicht überrascht, dass Microsoft dieses Zeug nicht richtig machen kann. Ich habe es entdeckt, weil ich eine Skriptdatei habe, die Referenztabellen auffüllt, die ich manchmal ausführe, nachdem ich Tabellen neu erstellt habe, und manchmal, wenn die Tabellen bereits erstellt wurden.

Costa
quelle
1

Ich benutze dazu das folgende Skript. Es gibt nur ein Szenario, in dem ein "Fehler" auftritt, wenn Sie alle Zeilen aus der Tabelle gelöscht haben und IDENT_CURRENTderzeit auf 1 gesetzt sind, dh es gab zunächst nur eine Zeile in der Tabelle.

DECLARE @maxID int = (SELECT MAX(ID) FROM dbo.Tbl)
;

IF @maxID IS NULL
    IF (SELECT IDENT_CURRENT('dbo.Tbl')) > 1
        DBCC CHECKIDENT ('dbo.Tbl', RESEED, 0)
    ELSE
        DBCC CHECKIDENT ('dbo.Tbl', RESEED, 1)
    ;
ELSE
    DBCC CHECKIDENT ('dbo.Tbl', RESEED, @maxID)
;
Chris Mack
quelle
0

Für eine vollständige DELETE-Zeile und das Zurücksetzen der IDENTITY-Anzahl verwende ich diese (SQL Server 2008 R2)

USE mydb

-- ##################################################################################################################
-- DANGEROUS!!!! USE WITH CARE
-- ##################################################################################################################

DECLARE
  db_cursor CURSOR FOR
    SELECT TABLE_NAME
      FROM INFORMATION_SCHEMA.TABLES
     WHERE TABLE_TYPE = 'BASE TABLE'
       AND TABLE_CATALOG = 'mydb'

DECLARE @tblname VARCHAR(50)
SET @tblname = ''

OPEN db_cursor
FETCH NEXT FROM db_cursor INTO @tblname

WHILE @@FETCH_STATUS = 0
BEGIN
  IF CHARINDEX('mycommonwordforalltablesIwanttodothisto', @tblname) > 0
    BEGIN
      EXEC('DELETE FROM ' + @tblname)
      DBCC CHECKIDENT (@tblname, RESEED, 0)
    END

  FETCH NEXT FROM db_cursor INTO @tblname
END

CLOSE db_cursor
DEALLOCATE db_cursor
GO
Fandango68
quelle
0

Das erneute Säen auf 0 ist nur dann sehr praktisch, wenn Sie den gesamten Tisch aufräumen.

ansonsten ist die Antwort von Anthony Raymond perfekt. Holen Sie sich zuerst das Maximum der Identitätsspalte und setzen Sie es dann mit max.

Ali Sufyan
quelle
0

Ich habe versucht, dies für eine große Anzahl von Tabellen während der Entwicklung zu erledigen, und dies funktioniert als Zauber.

DBCC CHECKIDENT('www.newsType', RESEED, 1);
DBCC CHECKIDENT('www.newsType', RESEED);

Sie erzwingen also zuerst, dass es auf 1 gesetzt wird, und setzen es dann auf den höchsten Index der in der Tabelle vorhandenen Zeilen. Schneller und einfacher Rest der Idee.

KimvdLinde
quelle
-2

Es ist immer besser, TRUNCATE zu verwenden, wenn dies möglich ist, als alle Datensätze zu löschen, da kein Protokollspeicherplatz verwendet wird.

Wenn wir den Startwert löschen und zurücksetzen müssen, denken Sie immer daran, dass, wenn die Tabelle nie gefüllt wurde und Sie sie verwendet haben, der DBCC CHECKIDENT('tablenem',RESEED,0) erste Datensatz die Identität = 0 erhält, wie in der msdn-Dokumentation angegeben

Erstellen Sie in Ihrem Fall nur den Index neu und sorgen Sie sich nicht um den Verlust der Identitätsserie, da dies ein häufiges Szenario ist.

Abdul Hannan Ijaz
quelle
3
Klingt für mich so, als ob die Idee darin besteht, nur einige Datensätze zu löschen .
Drumbeg
6
Dies ist einfach falsch - Es ist nicht IMMER besser, abgeschnitten zu verwenden, und in der Tat ist es nur in einigen sehr begrenzten und spezifischen Szenarien besser. Der Himmel verbietet jemandem, Ihrem Rat zu folgen und dann einen Rollback durchzuführen.
Thronk
1
@ Thronk Warum implizieren Sie, dass TRUNCATEdies verhindern würde, dass Sie ROLLBACKsich wie erwartet verhalten? ROLLBACK rollt immer noch zurück. Auch wenn die DB auf eingestellt ist BULK_LOGGED.
Solomon Rutzky
2
TRUNCATE ist eine DDL-Operation und wird nicht in der Protokolldatei protokolliert. Es sei denn, es ist Teil einer Transaktion (an keiner Stelle in der Frage oder in dieser Antwort erwähnt). Immer wenn jemand sagt, dass etwas IMMER wahr ist, ist es eine ziemlich sichere Wette, dass er falsch liegt.
Thronk
Dies ist die einzige Antwort, die feststellt, dass es einen Unterschied im RESEED-Verhalten gibt, je nachdem, ob die Sequenz zuvor verwendet wurde oder nicht. Eine Neueinstellung desselben Werts in mehreren leeren Tabellen, in denen einige Tabellen zuvor ausgefüllt wurden, führt zu unterschiedlichen Anfangswerten für den ersten in jede Tabelle eingefügten Datensatz.
Simon Coleman
-4

Erstens: Identitätsspezifikation Nur: "Nein" >> Datenbank speichern Projekt ausführen

Danach: Identitätsspezifikation Nur: "JA" >> Database Execute Project speichern

Ihre Datenbank-ID, PK Beginnen Sie mit 1 >>

Pratik Patel
quelle