pricing nube gratis create crear sql sql-server database sql-server-2008 azure-sql-database

nube - sql database download



Restablecer la semilla de identidad después de eliminar registros en SQL Server (17)

He insertado registros en una tabla de base de datos de SQL Server. La tabla tenía una clave principal definida y la semilla de identidad de incremento automático se establece en "Sí". Esto se hace principalmente porque en SQL Azure, cada tabla debe tener una clave primaria e identidad definida.

Pero como tengo que eliminar algunos registros de la tabla, la semilla de identidad de esas tablas se verá afectada y la columna de índice (que se genera automáticamente con un incremento de 1) se verá afectada.

¿Cómo puedo restablecer la columna de identidad después de eliminar los registros para que la columna tenga una secuencia en orden numérico ascendente?

La columna de identidad no se utiliza como clave externa en ninguna parte de la base de datos.


@jacob

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

Trabajé para mí, solo tenía que borrar todas las entradas de la tabla y luego agregar lo anterior en un punto de activación después de eliminar. Ahora cada vez que borre una entrada se toma de allí.


Aunque la mayoría de las respuestas sugieren RESEED a 0 , y si bien algunas ven esto como un defecto para las tablas TRUNCATED , Microsoft tiene una solución que excluye la ID

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

Esto verificará la tabla y se restablecerá a la siguiente ID . Esto ha estado disponible desde MS SQL 2005 hasta la fecha.

MSDN


Aunque la mayoría de las respuestas sugieren RESEED a 0, pero muchas veces necesitamos simplemente volver a ver la próxima Id disponible

declare @max int select @max=max([Id])from [TestTable] if @max IS NULL //check when max is returned as null SET @max = 0 DBCC CHECKIDENT (''[TestTable]'', RESEED,@max)

Esto verificará la tabla y se restablecerá a la siguiente ID.


Ejecute este script para restablecer la columna de identidad. Tendrá que hacer dos cambios. Reemplace tableXYZ con cualquier tabla que necesite actualizar. Además, el nombre de la columna de identidad debe eliminarse de la tabla temporal. Esto fue instantáneo en una tabla con 35,000 filas y 3 columnas. Obviamente, haga una copia de seguridad de la tabla y primero intente esto en un entorno de prueba.

select * into #temp From tableXYZ set identity_insert tableXYZ ON truncate table tableXYZ alter table #temp drop column (nameOfIdentityColumn) set identity_insert tableXYZ OFF insert into tableXYZ select * from #temp


Esta es una pregunta común y la respuesta es siempre la misma: no lo hagas. Los valores de identidad deben tratarse como arbitrarios y, como tales, no hay un orden "correcto".


Intenté @anil shahs responder y restablecer la identidad. Pero cuando se insertó una nueva fila, obtuvo la identity = 2 . Así que en lugar de eso cambié la sintaxis a:

DELETE FROM [TestTable] DBCC CHECKIDENT (''[TestTable]'', RESEED, 0) GO

Entonces la primera fila obtendrá la identidad = 1.


Para completar las filas DELETE y restablecer el recuento de IDENTIDAD, uso esto (SQL Server 2008 R2)

USE mydb -- ################################################################################################################## -- DANGEROUS!!!! USE WITH CARE -- ################################################################################################################## DECLARE db_cursor CURSOR FOR SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = ''BASE TABLE'' AND TABLE_CATALOG = ''mydb'' DECLARE @tblname VARCHAR(50) SET @tblname = '''' OPEN db_cursor FETCH NEXT FROM db_cursor INTO @tblname WHILE @@FETCH_STATUS = 0 BEGIN IF CHARINDEX(''mycommonwordforalltablesIwanttodothisto'', @tblname) > 0 BEGIN EXEC(''DELETE FROM '' + @tblname) DBCC CHECKIDENT (@tblname, RESEED, 0) END FETCH NEXT FROM db_cursor INTO @tblname END CLOSE db_cursor DEALLOCATE db_cursor GO


Primero: Especificación de identidad Solo: "No" >> Guardar proyecto de ejecución de base de datos

Después de eso: Especificación de identidad Just: "YES" >> Guardar proyecto de ejecución de base de datos

Su ID de base de datos, PK Inicio desde 1 >>


Restablecer la columna de identidad con nueva identificación ...

DECLARE @MAX INT SELECT @MAX=ISNULL(MAX(Id),0) FROM [TestTable] DBCC CHECKIDENT (''[TestTable]'', RESEED,@MAX)


Se debe tener en cuenta que SI todos los datos se eliminan de la tabla a través de DELETE (es decir, no hay una cláusula WHERE ), entonces siempre que a) los permisos lo permitan, yb) no haya FK que hagan referencia a la tabla (que aparece para ser el caso aquí, se preferiría usar TRUNCATE TABLE , ya que hace un DELETE más eficiente y restablece la semilla de IDENTITY al mismo tiempo. Los siguientes detalles se tomaron de la página de MSDN para TRUNCATE TABLE :

En comparación con la instrucción DELETE, TRUNCATE TABLE tiene las siguientes ventajas:

  • Se utiliza menos espacio de registro de transacciones.

    La instrucción DELETE elimina las filas una a la vez y registra una entrada en el registro de transacciones para cada fila eliminada. TRUNCATE TABLE elimina los datos al desasignar las páginas de datos utilizadas para almacenar los datos de la tabla y registra solo las desasignaciones de páginas en el registro de transacciones.

  • Normalmente se utilizan menos bloqueos.

    Cuando la instrucción DELETE se ejecuta utilizando un bloqueo de fila, cada fila de la tabla se bloquea para su eliminación. TRUNCATE TABLE siempre bloquea la tabla (incluido un bloqueo de esquema (SCH-M)) y la página, pero no cada fila.

  • Sin excepción, cero páginas quedan en la tabla.

    Después de ejecutar una instrucción DELETE, la tabla aún puede contener páginas vacías. Por ejemplo, las páginas vacías en un montón no pueden desasignarse sin al menos un bloqueo de tabla exclusivo (LCK_M_X). Si la operación de eliminación no utiliza un bloqueo de tabla, la tabla (montón) contendrá muchas páginas vacías. Para los índices, la operación de eliminación puede dejar páginas vacías atrás, aunque estas páginas se desasignarán rápidamente mediante un proceso de limpieza en segundo plano.

Si la tabla contiene una columna de identidad, el contador de esa columna se restablece al valor semilla definido para la columna. Si no se definió una semilla, se usa el valor predeterminado 1. Para retener el contador de identidad, use DELETE en su lugar.

Así que lo siguiente:

DELETE FROM [MyTable]; DBCC CHECKIDENT (''[MyTable]'', RESEED, 0);

Se convierte en justo:

TRUNCATE TABLE [MyTable];

Consulte la documentación de TRUNCATE TABLE (enlace arriba) para obtener información adicional sobre restricciones, etc.


Se prefiere Truncate tabla porque borra los registros, restablece el contador y recupera el espacio dis.

Delete and CheckIdent debe usar solo cuando las claves foráneas impidan que trunque


Siempre es mejor usar TRUNCATE cuando sea posible en lugar de eliminar todos los registros, ya que tampoco usa el espacio de registro.

En caso de que necesitemos eliminar y restablecer la semilla, siempre recuerde que si la tabla nunca se DBCC CHECKIDENT(''tablenem'',RESEED,0) y utilizó DBCC CHECKIDENT(''tablenem'',RESEED,0) , el primer registro obtendrá la identidad = 0 como se indica en la MSDN

En su caso, solo reconstruya el índice y no se preocupe por perder la serie de identidad, ya que este es un escenario común.


Utilice este procedimiento almacenado:

IF (object_id(''[dbo].[pResetIdentityField]'') IS NULL) BEGIN EXEC(''CREATE PROCEDURE [dbo].[pResetIdentityField] AS SELECT 1 FROM DUMMY''); END GO SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO ALTER PROCEDURE [dbo].[pResetIdentityField] @pSchemaName NVARCHAR(1000) , @pTableName NVARCHAR(1000) AS DECLARE @max INT; DECLARE @fullTableName NVARCHAR(2000) = @pSchemaName + ''.'' + @pTableName; DECLARE @identityColumn NVARCHAR(1000); SELECT @identityColumn = c.[name] FROM sys.tables t INNER JOIN sys.schemas s ON t.[schema_id] = s.[schema_id] INNER JOIN sys.columns c ON c.[object_id] = t.[object_id] WHERE c.is_identity = 1 AND t.name = @pTableName AND s.[name] = @pSchemaName IF @identityColumn IS NULL BEGIN RAISERROR( ''One of the following is true: 1. the table you specified doesn''''t have an identity field, 2. you specified an invalid schema, 3. you specified an invalid table'' , 16 , 1); RETURN; END; DECLARE @sqlString NVARCHAR(MAX) = N''SELECT @maxOut = max('' + @identityColumn + '') FROM '' + @fullTableName; EXECUTE sp_executesql @stmt = @sqlString, @params = N''@maxOut int OUTPUT'', @maxOut = @max OUTPUT IF @max IS NULL SET @max = 0 print(@max) DBCC CHECKIDENT (@fullTableName, RESEED, @max) go --exec pResetIdentityField ''dbo'', ''Table''

Solo revisando mi respuesta. Me encontré con un comportamiento extraño en el servidor sql 2008 r2 que debería tener en cuenta.

drop table test01 create table test01 (Id int identity(1,1), descr nvarchar(10)) execute pResetIdentityField ''dbo'', ''test01'' insert into test01 (descr) values(''Item 1'') select * from test01 delete from test01 execute pResetIdentityField ''dbo'', ''test01'' insert into test01 (descr) values(''Item 1'') select * from test01

La primera selección produce 0, Item 1 .

El segundo produce 1, Item 1 . Si ejecuta el reinicio justo después de crear la tabla, el siguiente valor es 0. Honestamente, no me sorprende que Microsoft no pueda hacer esto correctamente. Lo descubrí porque tengo un archivo de secuencia de comandos que llena las tablas de referencia que a veces ejecuto después de volver a crear las tablas y otras veces cuando las tablas ya están creadas.


emitir 2 comandos puede hacer el truco

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

el primero restablece la identidad a cero, y el siguiente lo establecerá en el siguiente valor disponible - jacob


El comando de administración DBCC CHECKIDENT se usa para restablecer el contador de identidad. La sintaxis del comando es:

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

Ejemplo:

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

No se admitía en versiones anteriores de la Base de datos SQL de Azure, pero ahora se admite.

Tenga en cuenta que el argumento new_reseed_value varía según las versiones de SQL Server de acuerdo con la documentación :

Si las filas están presentes en la tabla, la siguiente fila se inserta con el valor new_reseed_value . En la versión SQL Server 2008 R2 y anteriores, la siguiente fila insertada usa new_reseed_value + el valor de incremento actual.

Sin embargo, encuentro que esta información es engañosa (en realidad, simplemente errónea) porque el comportamiento observado indica que al menos SQL Server 2012 todavía usa new_reseed_value + la lógica del valor de incremento actual. Microsoft incluso contradice con su propio Example C encuentra en la misma página:

C. Forzar el valor de identidad actual a un nuevo valor

El siguiente ejemplo fuerza el valor de identidad actual en la columna AddressTypeID en la tabla AddressType a un valor de 10. Como la tabla tiene filas existentes, la siguiente fila insertada usará 11 como valor, es decir, el nuevo valor de incremento actual definido para el valor de la columna más 1.

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

Aún así, todo esto deja una opción para un comportamiento diferente en las nuevas versiones de SQL Server. Creo que la única manera de estar seguro, hasta que Microsoft aclare las cosas en su propia documentación, es hacer pruebas reales antes de usarlas.


DBCC CHECKIDENT (<TableName>, reseed, 0)

Esto establecerá el valor de identidad actual en 0.

Al insertar el siguiente valor, el valor de identidad se incrementa a 1.


DBCC CHECKIDENT (''TestTable'', RESEED, 0) GO

Donde 0 es valor de inicio de identity