SQL Server 2012列标识增量从第6条跳转到第1000条以上

我有一个奇怪的情况,我的SQL Server 2012数据库中的自动标识int列没有正确递增。

说我有一个表使用int自动标识作为主键,它是零星地跳过增量,例如:

1,2,3,4,5,1004,1005

这种情况发生在非常随机的随机数字表上,无法复制它以发现任何趋势。

这是怎么发生的? 有没有办法让它停止?

这完全正常。 微软在SQL Server 2012中添加了sequences ,最后,我可能会添加和更改生成身份密钥的方式。 看看这里的一些解释。

如果你想拥有旧的行为,你可以:

  1. 使用跟踪标志272 – 这将导致为每个生成的标识值生成日志logging。 打开此跟踪标志可能会影响身份生成的性能。
  2. 使用NO CACHE设置的序列发生器( http://msdn.microsoft.com/zh-cn/library/ff878091.aspx

我知道我的答案可能迟到了。 但我已经通过在SQL Server 2012中添加启动存储过程以另一种方式解决了。

在主数据库中创build以下存储过程。

 USE [master] GO SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO ALTER PROCEDURE [dbo].[ResetOrderIdentityAfterRestart] AS BEGIN begin TRAN declare @id int = 0 SELECT @id = MAX(id) FROM [DatabaseName].dbo.[TableName] --print @id DBCC CHECKIDENT ('[DatabaseName].dbo.[TableName]', reseed, @id) Commit END 

然后通过使用以下语法将其添加到启动。

 EXEC sp_procoption 'ResetOrderIdentityAfterRestart', 'startup', 'on'; 

如果你有几张桌子,这是一个好主意。 但如果你必须为许多表格做,这种方法仍然有效,但不是一个好主意。

得到了同样的问题,发现SQL Server 2012中的以下错误报告如果仍然相关,请参阅导致问题的条件 – 也有一些解决方法,以及(没有尝试虽然)。 重置身份的故障转移或重新启动结果

虽然跟踪标志272可能适用于很多,但它绝对不能用于托pipe的Sql Server Express安装。 所以,我创build了一个身份表,并通过一个INSTEAD OF触发器来使用它。 我希望这可以帮助别人,并且/或者让别人有机会改进我的解决scheme。 最后一行允许返回添加的最后一个标识列。 由于我通常使用这个来添加一个单独的行,所以这个工作可以返回一个插入行的标识。

身份证:

 CREATE TABLE [dbo].[tblsysIdentities]( [intTableId] [int] NOT NULL, [intIdentityLast] [int] NOT NULL, [strTable] [varchar](100) NOT NULL, [tsConcurrency] [timestamp] NULL, CONSTRAINT [PK_tblsysIdentities] PRIMARY KEY CLUSTERED ( [intTableId] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] 

和插入触发器:

 -- INSERT -- IF OBJECT_ID ('dbo.trgtblsysTrackerMessagesIdentity', 'TR') IS NOT NULL DROP TRIGGER dbo.trgtblsysTrackerMessagesIdentity; GO CREATE TRIGGER trgtblsysTrackerMessagesIdentity ON dbo.tblsysTrackerMessages INSTEAD OF INSERT AS BEGIN DECLARE @intTrackerMessageId INT DECLARE @intRowCount INT SET @intRowCount = (SELECT COUNT(*) FROM INSERTED) SET @intTrackerMessageId = (SELECT intIdentityLast FROM tblsysIdentities WHERE intTableId=1) UPDATE tblsysIdentities SET intIdentityLast = @intTrackerMessageId + @intRowCount WHERE intTableId=1 INSERT INTO tblsysTrackerMessages( [intTrackerMessageId], [intTrackerId], [strMessage], [intTrackerMessageTypeId], [datCreated], [strCreatedBy]) SELECT @intTrackerMessageId + ROW_NUMBER() OVER (ORDER BY [datCreated]) AS [intTrackerMessageId], [intTrackerId], [strMessage], [intTrackerMessageTypeId], [datCreated], [strCreatedBy] FROM INSERTED; SELECT TOP 1 @intTrackerMessageId + @intRowCount FROM INSERTED; END