Restablecer AutoIncrement en SQL Server después de Eliminar

266

He eliminado algunos registros de una tabla en una base de datos de SQL Server. Ahora las ID van de 101 a 1200. Quiero eliminar los registros nuevamente, pero quiero que las ID vuelvan a 102. ¿Hay alguna manera de hacer esto en SQL Server?

jumbojs
fuente
46
Por favor no digas "No lo hagas". Odio cuando pregunto cómo hacer algo y todo lo que obtengo es que no. Sí, restablecer la identidad puede causar problemas de clave externa, pero solo si no conoce su base de datos y programa en consecuencia. Hay muy buenas razones para restablecer una identidad después de una eliminación programada: se llaman Auditores. Los auditores odian ver los vacíos, así que complételos, hágalo de manera controlada y asegúrese de que se mantengan las restricciones de claves externas.
66
@spyder, ¿sabía que tendrá huecos si se revierte una inserción de registro no solo para eliminarla? No puede evitar lagunas con un aumento automático y es una tontería intentarlo. He trabajado para una agencia de auditoría y los auditores competentes pueden tener esto explicado. Además, si tiene tablas de auditoría adecuadas, pueden ver qué sucedió con esos registros. O si no debe haber brechas por razones legales (hay algunos casos de esto), entonces solo un desarrollador incompetente usaría un autoincremento y los auditores están molestos.
HLGEM

Respuestas:

457

Emita el siguiente comando para reiniciar mytable para comenzar en 1:

DBCC CHECKIDENT (mytable, RESEED, 0)

Lea sobre esto en los Libros en línea (BOL, ayuda de SQL). También tenga cuidado de no tener registros más altos que la semilla que está configurando.

Robert Wagner
fuente
44
... porque los identificadores de estos registros se reutilizarán felizmente nuevamente, causando un mal desastre.
nalply
3
En realidad, para comenzar las ID en 1, debe usar 0: DBCC CHECKIDENT (mytable, RESEED, 0)
Ryan Lundy
77
"DBCC CHECKIDENT (nombre_tabla)" establece la semilla en la identidad más alta de la tabla, de lo que no tiene que "tener cuidado"
usuario1027167
44
@ user1027167 No, su respuesta no funcionó para mí. Continuó incrementándose en la ID más alta que había guardado internamente. Tuve que usar explícitamente "RESEED, 18" en mi caso para obtener "19" como siguiente ID. Sin ello, siguió aumentando felizmente en "29".
Matthis Kohli
DBCC CHECKIDENT (nombre_tabla) solo cambia la semilla si el valor de identidad es inferior al valor máximo en la columna. Entonces, si el valor de identidad ya es más grande como el caso @MatthisKohli, se debe llamar a la reinicialización explícita.
Martheen
82
DBCC CHECKIDENT('databasename.dbo.tablename', RESEED, number)

si número = 0, en la siguiente inserción el campo de incremento automático contendrá el valor 1

si número = 101, en la siguiente inserción el campo de incremento automático contendrá el valor 102


Alguna información adicional ... Puede ser útil para usted

Antes de dar el incremento automático numberen la consulta anterior, debe asegurarse de que la columna de incremento automático de la tabla existente contenga valores menores number.

Para obtener el valor máximo de una columna (nombre_columna) de una tabla (tabla1), puede usar la siguiente consulta

 SELECT MAX(column_name) FROM table1
Fathah Rehman P
fuente
37

semi a prueba de idiotas:

declare @max int;  
select @max = max(key) from table;  
dbcc checkident(table,reseed,@max)

http://sqlserverplanet.com/tsql/using-dbcc-checkident-to-reseed-a-table-after-delete

usuario423430
fuente
1
"DBCC CHECKIDENT (nombre_tabla)" hace lo mismo (posible sin condiciones de carrera)
usuario1027167
2
@ user1027167 Los documentos dicen 'si el valor de identidad actual para una tabla es menor que el valor de identidad máximo almacenado en la columna de identidad'; eso no cubre la limpieza después de que se eliminen los datos (reutilizar los identificadores, a menudo es una mala idea). Verificado en SQL 2008
usuario423430
1
La mejor respuesta sistemática y automática. ¡Bravo!
Mehdi Khademloo
11

Si está utilizando MySQL, intente esto:

ALTER TABLE tablename AUTO_INCREMENT = 1
xaa
fuente
3
Esta es una respuesta para MySQL. OP pregunta sobre MSSQL.
reformado el
la pregunta es sobre MS SQL Server
Saher Ahwal
6

Eliminar y volver a colocar todas las tablas en una base de datos.

    USE [DatabaseName]
    EXEC sp_msforeachtable "ALTER TABLE ? NOCHECK CONSTRAINT all"       -- Disable All the constraints
    EXEC sp_MSForEachTable "DELETE FROM ?"    -- Delete All the Table data
    Exec sp_MSforeachtable 'DBCC CHECKIDENT(''?'', RESEED, 0)' -- Reseed All the table to 0
    Exec sp_msforeachtable "ALTER TABLE ? WITH CHECK CHECK CONSTRAINT all"  -- Enable All  the constraints back

-- You may ignore the errors that shows the table without Auto increment field.
BMG
fuente
6

Me lo imaginé. Sus:

 DBCC CHECKIDENT ('tablename', RESEED, newseed)
jumbojs
fuente
4

Basado en la respuesta aceptada, para aquellos que encontraron un problema similar, con calificación de esquema completo:

( [MyDataBase].[MySchemaName].[MyTable]) ... da como resultado un error, debe estar en el contexto de esa base de datos

Es decir, lo siguiente arrojará un error:

DBCC CHECKIDENT ([MyDataBase].[MySchemaName].[MyTable], RESEED, 0)

Incluya el nombre de la tabla completa con comillas simples en su lugar:

DBCC CHECKIDENT ('[MyDataBase].[MySchemaName].[MyTable]', RESEED, 0)
usuario919426
fuente
4

Varias respuestas recomiendan usar una declaración como esta:

DBCC CHECKIDENT (mytable, RESEED, 0)

Pero el OP dijo "eliminó algunos registros", que pueden no ser todos, por lo que un valor de 0 no siempre es el correcto. Otra respuesta sugirió encontrar automáticamente el valor actual máximo y volver a colocarlo en ese, pero eso tiene problemas si no hay registros en la tabla, y por lo tanto max () devolverá NULL. Un comentario sugerido usando simplemente

DBCC CHECKIDENT (mytable)

para restablecer el valor, pero otro comentario indicó correctamente que esto solo aumenta el valor al máximo que ya está en la tabla; esto no reducirá el valor si ya es más alto que el máximo en la tabla, que es lo que el OP quería hacer.

Una mejor solución combina estas ideas. El primer CHECKIDENT restablece el valor a 0, y el segundo lo restablece al valor más alto actualmente en la tabla, en caso de que haya registros en la tabla:

DBCC CHECKIDENT (mytable, RESEED, 0)
DBCC CHECKIDENT (mytable)

Como lo han indicado varios comentarios, asegúrese de que no haya claves externas en otras tablas que apunten a los registros eliminados. De lo contrario, esas claves foráneas apuntarán a los registros que cree después de volver a colocar la tabla, que seguramente no es lo que tenía en mente.

Michael Rodby
fuente
4

Quiero agregar esta respuesta porque el DBCC CHECKIDENTenfoque -producirá problemas cuando use esquemas para tablas. Use esto para estar seguro:

DECLARE @Table AS NVARCHAR(500) = 'myschema.mytable';
DBCC CHECKIDENT (@Table, RESEED, 0);

Si desea verificar el éxito de la operación, use

SELECT IDENT_CURRENT(@Table);

que debería salir 0en el ejemplo anterior.

Alexander Schmidt
fuente
1

No quieres hacer esto en general. Reseed puede crear problemas de integridad de datos. Realmente es solo para su uso en sistemas de desarrollo donde está borrando todos los datos de prueba y comenzando de nuevo. No debe usarse en un sistema de producción en caso de que no se hayan eliminado todos los registros relacionados (¡no todas las tablas que deberían estar en una relación de clave externa lo son!). Puede crear un desastre haciendo esto y especialmente si tiene la intención de hacerlo regularmente después de cada eliminación. Es una mala idea preocuparse por las brechas en sus valores de campo de identidad.

HLGEM
fuente
66
No lo usaré todo el tiempo y solo fue en una base de datos de prueba.
jumbojs
0

¿Qué hay de esto?

ALTER TABLE `table_name`
  MODIFY `id` int(12) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=0;

Esta es una forma rápida y sencilla de cambiar el incremento automático a 0 o el número que desee. Lo descubrí exportando una base de datos y leyendo el código yo mismo.

También puede escribirlo así para que sea una solución de una sola línea:

ALTER TABLE `table_name` MODIFY `id` int(12) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=0;
Victor Resnov
fuente
1
Gracias por este fragmento de código, que puede proporcionar una ayuda limitada e inmediata. Una explicación adecuada mejoraría en gran medida su valor a largo plazo al mostrar por qué esta es una buena solución al problema y lo haría más útil para futuros lectores con otras preguntas similares. Por favor, editar su respuesta a añadir un poco de explicación, incluyendo los supuestos realizados.
Goodbye StackExchange