2010-03-02 4 views
20

Grundsätzlich muss ich Identity Increment für alle Tabellen auf sein Original zurücksetzen. Hier habe ich etwas Code versucht, aber es schlägt fehl.SQL Server Reset Identity Inkrement für alle Tabellen

http://pastebin.com/KSyvtK5b

aktuelle Code von Link:

USE World00_Character 
GO 

-- Create a cursor to loop through the System Ojects and get each table name 
DECLARE TBL_CURSOR CURSOR 
-- Declare the SQL Statement to cursor through 
FOR (SELECT Name FROM Sysobjects WHERE Type='U') 

-- Declare the @SQL Variable which will hold our dynamic sql 
DECLARE @SQL NVARCHAR(MAX); 
SET @SQL = ''; 
-- Declare the @TblName Variable which will hold the name of the current table 
DECLARE @TblName NVARCHAR(MAX); 

-- Open the Cursor 
OPEN TBL_CURSOR 

-- Setup the Fetch While that will loop through our cursor and set @TblName 
FETCH NEXT FROM TBL_CURSOR INTO @TblName 
-- Do this while we are not at the end of the record set 
WHILE (@@FETCH_STATUS <> -1) 
BEGIN 
-- Appeand this table's select count statement to our sql variable 
SET @SQL = @SQL + ' (SELECT '''[email protected]+''' AS Table_Name,COUNT(*) AS Count FROM '[email protected]+') UNION'; 

-- Delete info 
EXEC('DBCC CHECKIDENT ('[email protected]+',RESEED,(SELECT IDENT_SEED('[email protected]+')))'); 

-- Pull the next record 
FETCH NEXT FROM TBL_CURSOR INTO @TblName 
-- End the Cursor Loop 
END 

-- Close and Clean Up the Cursor 
CLOSE TBL_CURSOR 
DEALLOCATE TBL_CURSOR 

-- Since we were adding the UNION at the end of each part, the last query will have 
-- an extra UNION. Lets trim it off. 
SET @SQL = LEFT(@SQL,LEN(@SQL)-6); 

-- Lets do an Order By. You can pick between Count and Table Name by picking which 
-- line to execute below. 
SET @SQL = @SQL + ' ORDER BY Count'; 
--SET @SQL = @SQL + ' ORDER BY Table_Name'; 

-- Now that our Dynamic SQL statement is ready, lets execute it. 
EXEC (@SQL); 
GO 

Fehlermeldung:

Error: Msg 102, Level 15, State 1, Line 1 Incorrect syntax near '('. 

Wie kann ich entweder reparieren, dass SQL oder zurückgesetzt Identität für alle Tabellen in seinem ursprünglichen?

Danke

Antwort

52

Haben Sie viele Tabellen haben, die keinen Samen und Zuwachs von 1 haben ??

Wenn nicht (standardmäßig alle Tabellen haben, dass), verwenden Sie diesen Code:

exec sp_MSforeachtable @command1 = 'DBCC CHECKIDENT(''?'', RESEED, 1)' 

MSforeachtable ist eine nicht dokumentierte, aber äußerst praktisch gespeicherte Prozedur, die einen gegebenen Befehl für alle Tabellen in der Datenbank ausgeführt wird.

Wenn Sie absolut genau sein, diese Anweisung verwenden - es wird eine Liste von SQL-Anweisungen generiert alle Tabellen auf ihren ursprünglichen SEED Wert reseed:

SELECT 
    IDENT_SEED(TABLE_NAME) AS Seed, 
    IDENT_INCR(TABLE_NAME) AS Increment, 
    IDENT_CURRENT(TABLE_NAME) AS Current_Identity, 
    TABLE_NAME, 
    'DBCC CHECKIDENT(' + TABLE_NAME + ', RESEED, ' + CAST(IDENT_SEED(TABLE_NAME) AS VARCHAR(10)) + ')' 
FROM 
    INFORMATION_SCHEMA.TABLES 
WHERE 
    OBJECTPROPERTY(OBJECT_ID(TABLE_NAME), 'TableHasIdentity') = 1 
    AND TABLE_TYPE = 'BASE TABLE' 

Schnappen Sie sich, letzte Spalte in der Ausgabe und führe diese Anweisungen aus und du bist fertig! :-)

(von einem blog post von Pinal Dave inspiriert)

+0

Nun, ich habe wie 80 Tabellen mit Standardsaatgut 101 und dann wie 50 mit 10001 und weitere 50 mit 1. Also habe ich versucht in SQL irgendwie Schleife zu tun, sondern wird versuchen, mit PHP tun Schleife, die einfacher sein könnte . – DanSpd

+0

@DanSpd: aktualisierte meine Antwort mit Ihrer ultimativen und absolut genauen Art, dies zu tun! :-) Genießen. –

+0

Vielen Dank.Macht meine Arbeit viel einfacher :) Ich liebe euch – DanSpd

2

Eine einfache metod kann den sp_MSforeachtable Befehl, eine undokumentierte zu verwenden, aber relativ gut Befehl, dass über Ihre Tabellen aussieht.

11

Geringfügige Optimierung der Antwort von marc_s.

exec sp_MSforeachtable @command1 = 'DBCC CHECKIDENT (''?'', RESEED)' 

Die einzelnen Anführungszeichen um die? Charakter sind wichtig. Diese Anweisung bewirkt, dass SQL Server den nächsten Identitätswert für jede Tabelle automatisch neu berechnet.

+0

Cool danke, war nur auf der Suche nach diesem! –

5

Leichte Abweichungen, die Schemen etwas besser behandelt ...

SELECT 
    IDENT_SEED(TABLE_SCHEMA+'.'+TABLE_NAME) AS Seed, 
    IDENT_INCR(TABLE_SCHEMA+'.'+TABLE_NAME) AS Increment, 
    IDENT_CURRENT(TABLE_SCHEMA+'.'+TABLE_NAME) AS Current_Identity, 
    TABLE_SCHEMA+'.'+TABLE_NAME, 
    'DBCC CHECKIDENT('''+TABLE_SCHEMA+'.'+TABLE_NAME+''', RESEED, '+CAST(IDENT_SEED(TABLE_SCHEMA+'.'+TABLE_NAME) AS VARCHAR(10))+')' 
FROM 
    INFORMATION_SCHEMA.TABLES 
WHERE 
    OBJECTPROPERTY(OBJECT_ID(TABLE_SCHEMA+'.'+TABLE_NAME), 'TableHasIdentity') = 1 
AND TABLE_TYPE = 'BASE TABLE' 
ORDER BY TABLE_SCHEMA, TABLE_NAME 
2

nur Tabellen mit einer Identitätsspalte reseed Sie das nächste Skript verwenden können. Es verwendet auch sp_MSforeachtable, aber unter Berücksichtigung der richtigen Tabellen.

EXEC sp_MSforeachtable ' 
IF (SELECT COUNT(1) 
    FROM INFORMATION_SCHEMA.TABLES 
    WHERE TABLE_TYPE = ''BASE TABLE'' 
    AND ''[''+ TABLE_SCHEMA + ''].['' + TABLE_NAME + '']'' = ''?'' 
    AND OBJECTPROPERTY(OBJECT_ID(TABLE_NAME), ''TableHasIdentity'') = 1) > 0 
BEGIN 
    DBCC CHECKIDENT (''?'', RESEED, 1) 
END' 
0

den Code unten verwenden,

CREATE TABLE #tmptable 
(
    [seednvalue] int not null, 
    [tablename] [nvarchar] (100) NULL 
) 


declare @seedvalue AS INT 
DECLARE @tablename AS VARCHAR(100) 

Declare #tablesIdentityCursor CURSOR 
    for 
    SELECT 
    IDENT_CURRENT(TABLE_NAME)+1 AS Current_Identity, 
    TABLE_NAME 
    FROM INFORMATION_SCHEMA.TABLES 
    WHERE OBJECTPROPERTY(OBJECT_ID(TABLE_NAME), 'TableHasIdentity') = 1 
    AND TABLE_TYPE = 'BASE TABLE' --AND TABLE_NAME='test11' 

delete from #tmptable 
Open #tablesIdentityCursor 
FETCH NEXT FROM #tablesIdentityCursor into @seedvalue, @tablename 
WHILE @@FETCH_STATUS = 0 BEGIN 

    Insert into #tmptable Select @seedvalue , @tablename 
    DBCC CHECKIDENT (@tablename, reseed, @seedvalue) 
    FETCH NEXT FROM #tablesIdentityCursor into @seedvalue, @tablename 
END 
CLOSE #tablesIdentityCursor 
DEALLOCATE #tablesIdentityCursor 
SELECT * FROM #tmptable 
DROP TABLE #tmptable 
2

Einen anderen Weg, sp_MSForEachTable von verwenden und prüfen, ob die Tabelle einen Identitätswert hat es vor dem Zurücksetzen:

EXEC sp_MSForEachTable ' 
Print ''?'' 
IF OBJECTPROPERTY(object_id(''?''), ''TableHasIdentity'') = 1 
    DBCC CHECKIDENT (''?'', RESEED, 0) 
else 
    Print ''Table does not have an identity value'' 
' 

HINWEIS: Wenn der Identitätswert bei 1 beginnen soll, sollte der DBCC-Befehl CHECKIDENT (''?'', RESEED, 0) nicht CHECKIDENT (''?'', RESEED, 1) als ind verwenden in einigen der Antworten. Zitat aus MS SQL Server documentation:

Das folgende Beispiel zwingt den aktuellen Kennwert in der AddressTypeID Spalte in der Tabelle Address auf einen Wert von 10.en Da die Tabelle hat vorhandene Zeilen, die nächste Zeile eingefügt wird 11 verwenden als der Wert ist, das heißt, die neue aktuelle Inkrementwert für den Spaltenwert definiert zuzüglich 1

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

Perfekt, ich habe nur ein '? 'In der Print-Anweisung wusste ich also, welche Tabelle keine Identität hatte. –

5

Seien Sie vorsichtig, wenn Sie diesen Befehl verwenden, wenn Ihre Tabellendaten alle neuen Einsätze enthält, wird res ult doppelte Fehler

exec sp_MSforeachtable @command1 = 'DBCC CHECKIDENT(''?'', RESEED,1)' 

das Problem, das Sie dies dies auf die letzte Spalte Identität wird zurückgesetzt, den Samen nach dem

exec sp_MSforeachtable @command1 = 'DBCC CHECKIDENT(''?'', RESEED)' 

ausführen müssen zu lösen, wenn die Daten

0

(I'm reposting my answer from this other SO page)

existiert

Vielleicht ist der einfachste Weg (so verrückt wie das klingt und Code-stinkig wie es aussieht), einfach DBCC CHECKIDENT zweimal so zu laufen:

-- sets all the seeds to 1 
exec sp_MSforeachtable @command1 = 'DBCC CHECKIDENT (''?'', RESEED, 1)' 

-- run it again to get MSSQL to figure out the MAX/NEXT seed automatically 
exec sp_MSforeachtable @command1 = 'DBCC CHECKIDENT (''?'')' 

Fertig.

Wenn Sie möchten, können Sie es noch einmal zu sehen laufen, was alle Samen gesetzt wurden:

-- run it again to display what the seeds are now set to 
exec sp_MSforeachtable @command1 = 'DBCC CHECKIDENT (''?'')' 

Dies ist nur eine kreative Art und Weise ist, den Vorteil des Kommentars aus der Dokumentation zu nehmen:

Wenn der aktuelle Identitätswert für eine Tabelle kleiner als der in der Identitätsspalte gespeicherte maximale Identitätswert ist, wird er unter Verwendung des Maximalwerts in der Identitätsspalte zurückgesetzt.

Verwandte Themen