Reset identity seed after deleting records in SQL Server
我已将记录插入到SQL Server数据库表中。该表定义了一个主键,并且自动递增标识种子设置为"是"。这主要是因为在SQLAzure中,每个表都必须定义一个主键和标识。
但是由于我必须从表中删除一些记录,这些表的标识种子将受到干扰,索引列(增量为1时自动生成)将受到干扰。
如何在删除记录后重置标识列,以使该列具有升序数字顺序?
标识列未用作数据库中任何位置的外键。
1 2 | DBCC CHECKIDENT (TABLE_NAME [, { NORESEED | { RESEED [, new_reseed_value ]}}]) [ WITH NO_INFOMSGS ] |
例子:
1 2 | DBCC CHECKIDENT ('[TestTable]', RESEED, 0); GO |
它是在以前的版本不支持SQL Azure数据库A大学,但现在是支持的。
请注意,在SQL Server
If rows are present in the table, the next row is inserted with the new_reseed_value value. In version SQL Server 2008 R2 and earlier, the next row inserted uses new_reseed_value + the current increment value.
然而,我发现这对于成本(只是平原是错误的信息,因为观察到的行为表明),至少是不使用SQL Server 2012年新_ reseed _值+当前增量的价值逻辑。微软甚至有其自己的contradicts
C. Forcing the current identity value to a new value
The following example forces the current identity value in the
AddressTypeID column in the AddressType table to a value of 10.
Because the table has existing rows, the next row inserted will use 11
as the value, that is, the new current increment value defined for the
column value plus 1.
1 2 3 4 | USE AdventureWorks2012; GO DBCC CHECKIDENT ('Person.AddressType', RESEED, 10); GO |
安静,这所有的叶子在不同的行为选择对新的SQL Server版本。我想唯一的方式来确保清晰的东西在动,直到微软自己的文档,是做实际测试之前使用。
1 2 | DBCC CHECKIDENT ('TestTable', RESEED, 0) GO |
在
应该指出,如果所有的数据是删除从表(IU)以
Compared to the DELETE statement, TRUNCATE TABLE has the following advantages:
Less transaction log space is used.
The DELETE statement removes rows one at a time and records an entry in the transaction log for each deleted row. TRUNCATE TABLE removes the data by deallocating the data pages used to store the table data and records only the page deallocations in the transaction log.
Fewer locks are typically used.
When the DELETE statement is executed using a row lock, each row in the table is locked for deletion. TRUNCATE TABLE always locks the table (including a schema (SCH-M) lock) and page but not each row.
Without exception, zero pages are left in the table.
After a DELETE statement is executed, the table can still contain empty pages. For example, empty pages in a heap cannot be deallocated without at least an exclusive (LCK_M_X) table lock. If the delete operation does not use a table lock, the table (heap) will contain many empty pages. For indexes, the delete operation can leave empty pages behind, although these pages will be deallocated quickly by a background cleanup process.
If the table contains an identity column, the counter for that column is reset to the seed value defined for the column. If no seed was defined, the default value 1 is used. To retain the identity counter, use DELETE instead.
那么下面的:
1 2 | DELETE FROM [MyTable]; DBCC CHECKIDENT ('[MyTable]', RESEED, 0); |
成就:
1 | TRUNCATE TABLE [MyTable]; |
请
我们建议的答案是最reseed为0,但许多次我们需要准时到下一个reseed ID
1 2 3 4 5 | 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) |
这将重置检查表和下一个ID。
我想把它
1 2 3 4 | DELETE FROM [TestTable] DBCC CHECKIDENT ('[TestTable]', RESEED, 0) GO |
然后第一行要把形象= 1。
虽然大多数的答案是对是
1 | DBCC CHECKIDENT ('[TestTable]', RESEED) |
这将检查表和一
http://。/en-US /图书馆/ ms176057.aspx
这是一个普通的问题,答案总是一样的:Don’t做它。标识应为任意值的搜索和处理,即,没有"正确"的命令。
"雅各
1 2 | DBCC CHECKIDENT ('[TestTable]', RESEED,0) DBCC CHECKIDENT ('[TestTable]', RESEED) |
为我工作,我不得不先清除所有条目从表A中,然后添加上面的触发点后删除。现在每当我删除条目是在采取从那里。
2发布命令可以做的把戏
1 2 | DBCC CHECKIDENT ('[TestTable]', RESEED,0) DBCC CHECKIDENT ('[TestTable]', RESEED) |
第一复位的零和一的身份,希望它的下一个值的集合-雅各布
因为它将是首选的
一个新的ID识别柱复位。
1 2 3 4 | DECLARE @MAX INT SELECT @MAX=ISNULL(MAX(Id),0) FROM [TestTable] DBCC CHECKIDENT ('[TestTable]', RESEED,@MAX) |
运行一个脚本识别柱复位。你需要做的两个变化。无论你需要tablexyz replace一表更新。所以,需要把名字识别柱表没有温度。这是一个新的表行瞬时&;3列。显然,这与第一次备份表中的测试环境。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 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 |
使用此存储过程:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | 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' |
只是回顾一下我的答案。我在SQL Server 2008 R2中遇到了一个您应该注意的奇怪行为。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | 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 |
第一个选择产生
第二个产生
1 | DBCC CHECKIDENT (<TableName>, reseed, 0) |
本想流标识值设置为0。
在一inserting价值、形象价值incremented get to 1。
我使用下面的脚本来执行此操作。只有一种情况会产生"错误",即如果删除了表中的所有行,并且
1 2 3 4 5 6 7 8 9 10 11 12 | DECLARE @maxID INT = (SELECT MAX(ID) FROM dbo.Tbl) ; IF @maxID IS NULL IF (SELECT IDENT_CURRENT('dbo.Tbl')) > 1 DBCC CHECKIDENT ('dbo.Tbl', RESEED, 0) ELSE DBCC CHECKIDENT ('dbo.Tbl', RESEED, 1) ; ELSE DBCC CHECKIDENT ('dbo.Tbl', RESEED, @maxID) ; |
对于完整的删除行和重置标识计数,我使用这个(SQL Server 2008 R2)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | 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 |
它总是最好使用TRUNCATE可能不是通过您的所有记录,当它不使用,所以日志空间。
我们需要删除的情况和需要复位的种子,永远记住,如果你使用的是不populated表
In your case only rebuild the index and don't worry about losing the
series of identity as this is a common scenario.
第一:标识规范只是:"否">>保存数据库执行项目
之后:标识规范只是:"是">>保存数据库执行项目
您的数据库ID,pk从1开始>>