1036 Stimmen

Zurücksetzen des Identitäts-Saatguts nach dem Löschen von Datensätzen in SQL Server

Ich habe Datensätze in eine Tabelle einer SQL Server-Datenbank eingefügt. Die Tabelle hatte einen Primärschlüssel definiert und der automatische inkrementelle Identitäts-Seed ist auf "Ja" gesetzt. Dies geschieht primär, weil in SQL Azure jede Tabelle einen Primärschlüssel und eine Identität haben muss.

Aber da ich einige Datensätze aus der Tabelle löschen muss, wird der Identitäts-Seed 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, damit die Spalte eine Sequenz in aufsteigender numerischer Reihenfolge hat?

Die Identitätsspalte wird in der Datenbank nirgendwo als Fremdschlüssel verwendet.

25voto

RealSollyM Punkte 1450

Auch wenn die meisten Antworten vorschlagen, RESEED auf 0 zu setzen, und obwohl einige dies als Fehler für TRUNCATED Tabellen sehen, hat Microsoft eine Lösung, die das ID ausschließt.

DBCC CHECKIDENT ('[TestTable]', RESEED)

Dadurch wird die Tabelle überprüft und auf die nächste ID zurückgesetzt. Diese Funktion ist seit MS SQL 2005 verfügbar.

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

16voto

jacob Punkte 175

Das Ausführen von 2 Befehlen kann das Problem lösen

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

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

13voto

Trent Punkte 121

Ich habe gerade DBCC CHECKIDENT erfolgreich verwendet

Zu beachten:

  • beim Bezug auf Tabellennamen werden eckige Klammern nicht akzeptiert
  • DBCC CHECKIDENT('Tabellenname',RESEED,n) wird auf n+1 zurückgesetzt
    • z.B. DBCC CHECKIDENT('tabellenname',RESEED,27) wird bei 28 starten
  • wenn Sie Probleme haben, die neue Start-ID nicht festzulegen - beachten Sie, dass Sie dies beheben können durch:

    DECLARE @NewId as INT  
    SET @NewId =  (SELECT MAX('TableName')-1  AS ID FROM TableName)
    DBCC CHECKIDENT('TableName',RESEED,@MaxId)

11voto

epic Punkte 91

@jacob

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

Hat für mich funktioniert, ich musste einfach zuerst alle Einträge in der Tabelle löschen, dann das oben genannte in einem Trigger-Punkt nach dem Löschen hinzufügen. Jetzt wird immer, wenn ich einen Eintrag lösche, von dort genommen.

11voto

abolfazl sadeghi Punkte 2167

Sie können CHECKIDENT verwenden, um das Seed zurückzusetzen

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

Beispiel

 DBCC CHECKIDENT ('TAble', reseed,0)

-- Beispielabfrage

Sie können die Grunddaten mit den folgenden Codes einfügen

Erstellen Sie zuerst eine Tabelle und fügen Sie dann Daten in die Tabelle ein

Schritt für Schritt zeige ich Daten an und entferne Daten, um Details für das Verständnis des Codes anzuzeigen

Ergebniscode: Tabelle mit zurückgesetzter IDs erstellen Ich verwendete die DMV sys.identity_columns, um festzustellen, ob die Tabelle ein Identitätsattribut hat

--Tabelle erstellen
DROP TABLE IF EXISTS  ExampleTable
create table ExampleTable (Id Bigint identity(1,1), Name nvarchar(10))

--In ExampleTable einfügen und Löschen und Identität anzeigen
insert into ExampleTable (Name) 
select 'Test1' as NAme union all select 'Test2' as NAme

select * from ExampleTable

| Id       | Name |
| -------- | -----|
| 1        |Test1 |
| 2        |Test2 |

delete from ExampleTable

insert into ExampleTable (Name) select 'Test3' as NAme

select * from ExampleTable

| Id       | Name |
| -------- | -----|
| 3        |Test3 |

delete from ExampleTable

Zuerst Daten prüfen Wenn die Tabelle keine Daten enthält, verwenden Sie den Seed-Wert

Wenn die Tabelle Daten enthält, verwenden Sie die Maximal-ID

Nach der Änderung des Seeds mit CHECKIDENT

--Seed-Tabelle finden
declare @reseed int=0

if(not exists( select top 1 * from ExampleTable))
begin

     SELECT 
        @reseed=cast( seed_value as int)
    FROM sys.tables tables 
        JOIN sys.identity_columns identity_columns 
    ON tables.object_id=identity_columns.object_id
    where 
        tables.name='ExampleTable' 
    and OBJECT_SCHEMA_NAME(tables.object_id, db_id())='dbo'

      set @reseed=@reseed -1

 end
 else
 begin
   --Wenn die Tabelle Daten enthält und Max-ID für Seed verwendet
    set @reseed=(select top 1 id from ExampleTable order by id desc)

 end

  DBCC CHECKIDENT ('ExampleTable', reseed,@reseed)

insert into ExampleTable
(Name)
select 'Test4' as NAme

select * from ExampleTable

| Id       | Name |
| -------- | -----|
| 1        |Test4 |

GO

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X