2010-03-02 12 views
20

Fondamentalmente ho bisogno di ripristinare l'Incremento di identità per tutte le tabelle al suo originale. Qui ho provato un po 'di codice, ma fallisce.SQL Server Reset Incremento identità per tutte le tabelle

http://pastebin.com/KSyvtK5b

codice vero e proprio dal 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 

messaggio di errore:

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

Come posso neanche rimediare SQL o ripristinare l'identità per tutte le tabelle al suo originale?

Grazie

risposta

52

Avete un sacco di tavoli che non hanno un seme e incremento di 1 ??

In caso contrario (per impostazione predefinita, tutte le tabelle hanno che), utilizzare questo codice:

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

MSforeachtable è un proc non documentata, ma estremamente utile memorizzato che esegue un determinato comando contro tutte le tabelle nel database.

Se avete bisogno di essere assolutamente precisa, utilizzare questa istruzione - verrà generato un elenco di istruzioni SQL per reseed tutti i tavoli al loro valore seme originale:

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' 

Grab che ultima colonna nell'output, e esegui quelle dichiarazioni e il gioco è fatto! :-)

(ispirato a un blog post da Pinal Dave)

+0

Beh io sono come 80 tabelle con seme di default 101 e poi come 50 con 10001 e un altro 50 con 1. Così ho cercato di fare un po loop in SQL, ma cercherà fare ciclo con PHP che potrebbe essere più facile . – DanSpd

+0

@DanSpd: aggiornato la mia risposta con il tuo modo definitivo e assolutamente preciso di farlo! :-) Godere. –

+0

Grazie mille.Rende il mio lavoro molto più semplice :) Ti amo ragazzi – DanSpd

2

Un Metod facile potrebbe essere quella di utilizzare il comando sp_MSforeachtable, una non documentata, ma relativamente ben noto comando che domina le tabelle.

11

Leggero tweak sulla risposta di marc_s.

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

Quelle virgolette singole intorno al? il carattere è importante Tale istruzione farà sì che SQL Server ricalcoli automaticamente il successivo valore di identità per ogni tabella.

+0

Grazie fantastici, cercavo solo questo! –

5

leggera variazione che gestisce gli schemi un po 'meglio ...

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

Per reseed tabelle solo con una colonna di identità è possibile utilizzare lo script successivo. Utilizza anche sp_MSforeachtable ma tenendo conto delle tabelle corrette.

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

Utilizzare il codice qui sotto,

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

Un altro modo di utilizzare sp_MSForEachTable e controllando se la tabella ha un valore di identità prima di resettarlo:

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

NOTA: Se si desidera che il valore dell'identità inizi a 1, il comando DBCC deve utilizzare CHECKIDENT (''?'', RESEED, 0) non CHECKIDENT (''?'', RESEED, 1) come ind indicato in alcune delle risposte. Citazione da MS SQL Server documentation:

Il seguente esempio forza il valore Identity corrente nella colonna AddressTypeID nella tabella AddressType ad un valore di 10. Poiché la tabella ha righe esistente, la successiva riga inserita userà 11 come il valore, che è, il nuovo valore di incremento corrente definito per il valore colonna più 1

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

Perfetto, ho solo aggiunto un '? 'nella dichiarazione di stampa quindi sapevo che tabella non aveva un'identità. –

5

fare attenzione quando si utilizza questo comando se la tabella contiene i dati tutti i nuovi inserti sarà res ult duplicare errore

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

per risolvere il problema è necessario eseguire questo dopo che

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

questo ripristinerà il seme fino all'ultima identità colonna se il dato esiste

0

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

Forse il modo più semplice (pazzesco come questo suona e come puzzolente come sembra) è quello di eseguire solo DBCC CHECKIDENT due volte in questo modo:

-- 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 (''?'')' 

Fatto.

Se si desidera, è possibile eseguirlo una volta di più per vedere che cosa tutti i semi sono stati fissati per:

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

Questo è solo un modo creativo per sfruttare il commento dalla documentazione:

Se il valore di identità corrente per una tabella è inferiore al valore di identità massimo memorizzato nella colonna Identità, viene reimpostato utilizzando il valore massimo nella colonna Identità.

Problemi correlati