2010-03-02 18 views
20

Básicamente, debo restablecer el Incremento de identidad para todas las tablas a su original. Aquí probé un código, pero falla.SQL Server Restablecer el aumento de identidad para todas las tablas

http://pastebin.com/KSyvtK5b

código real del enlace:

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 

mensaje de error:

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

¿Cómo se puede arreglar, ya sea que SQL o restablecer la identidad de todas las tablas a su estado original?

Gracias

Respuesta

52

¿Tiene un montón de tablas que no tienen una semilla y el incremento de 1 ??

Si no es así (por defecto, todas las tablas tienen que), utilice este código:

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

MSforeachtable es un procedimiento almacenado indocumentado, pero extremadamente útil que ejecuta un comando contra todas las tablas de la base de datos.

Si tiene que ser absolutamente exacta, utilice esta declaración - que va a generar una lista de sentencias SQL para sembrar de nuevo todas las tablas a su valor semilla original:

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' 

agarrar esa última columna en la salida, y ejecuta esas declaraciones y listo! :-)

(inspirado por un blog post por Pinal de Dave)

+0

Bueno, tengo como 80 mesas con semilla por defecto 101 y entonces como 50 con 10001 y otro 50 por 1. así que traté de hacer un poco de bucle en SQL, sino que tratará de hacer lazo con PHP que podría ser más fácil . – DanSpd

+0

@DanSpd: actualicé mi respuesta con su forma definitiva y absolutamente exacta de hacerlo. :-) Disfruta. –

+0

Muchas gracias.Hace mi trabajo mucho más fácil :) Los amo muchachos – DanSpd

2

Un metod fácil puede ser el uso del comando sp_MSforeachtable, un indocumentado, pero relativamente bien conocido comando que se ve sobre las tablas.

11

Leve modificación en la respuesta de marc_s.

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

¿Esas comillas simples alrededor? el personaje es importante. Esa declaración hará que SQL Server vuelva a calcular automáticamente el siguiente valor de identidad para cada tabla.

+0

¡Muchas gracias, solo estaba buscando esto! –

5

Una pequeña variación que maneja esquemas un poco mejor ...

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

reseed tablas sólo con una columna de identidad se puede utilizar la siguiente secuencia de comandos. También hace uso de sp_MSforeachtable pero teniendo en cuenta las tablas correctas.

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

Utilice el código de abajo,

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

Otra forma de utilizar sp_MSForEachTable y comprobar si la tabla tiene un valor de identidad antes de restablecerlo:

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

NOTA: Si desea que el valor de identidad comience en 1, entonces el comando DBCC debe usar CHECKIDENT (''?'', RESEED, 0) no CHECKIDENT (''?'', RESEED, 1) como ind icated en algunas de las respuestas. Presupuesto de MS SQL Server documentation:

el ejemplo siguiente se obliga al valor de identidad actual en la columna de la AddressTypeID en la tabla AddressType a un valor de 10. Dado que la tabla tiene filas existente, la siguiente fila insertada utilizará 11 como el valor, es decir, el nuevo valor mínimo de la corriente definida por el valor columna más 1

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

Perfecto, ¿solo agregué un '? 'en la declaración impresa, así que sabía qué tabla no tenía identidad. –

5

tener cuidado al usar este comando si la tabla contiene datos de todos sus nuevos insertos voluntad res ULT duplicar error

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

para resolver el problema es necesario ejecutar esto después de que

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

esto se restablecerá la semilla hasta la última identidad de la columna si existen los datos

0

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

Quizás la forma más fácil (tan loco como suena y tan maloliente como parece) es simplemente ejecutar DBCC CHECKIDENT dos veces como este:

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

Listo.

Si lo desea, puede ejecutar una vez más para ver lo que todas las semillas se colocaron a:

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

Esto es sólo una manera creativa para aprovechar el comentario de la documentación:

Si el valor de identidad actual de una tabla es menor que el valor de identidad máximo almacenado en la columna de identidad, se restablece utilizando el valor máximo de en la columna de identidad.

Cuestiones relacionadas