SQL Server 2012列标识增量在第7个条目上从6跳到1000+

时间:2013-01-04 18:19:24

标签: sql sql-server sql-server-2012 identity

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

假设我有一个使用int自动标识作为主键的表,它偶尔会跳过增量,例如:

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

这是在随机数量的随机时间表上发生的,无法复制它以查找任何趋势。

这是怎么回事? 有没有办法让它停止?

3 个答案:

答案 0 :(得分:74)

这一切都很正常。 Microsoft在SQL Server 2012中添加了sequences,最后,我可能会添加和更改生成身份密钥的方式。看看here进行一些解释。

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

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

答案 1 :(得分:4)

遇到同样的问题,在SQL Server 2012中发现了以下错误报告 如果仍然相关,请参阅导致问题的条件 - 那里也有一些解决方法(尽管没有尝试)。 Failover or Restart Results in Reseed of Identity

答案 2 :(得分:1)

虽然跟踪标志272可能适用于许多人,但它肯定不适用于托管的Sql Server Express安装。因此,我创建了一个标识表,并通过INSTEAD OF触发器使用它。我希望这可以帮助别人,和/或让其他人有机会改进我的解决方案。最后一行允许返回添加的最后一个标识列。由于我通常使用它来添加单行,因此可以返回单个插入行的标识。

身份表:

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