首页 文章

SQL Server 2012列标识增量从第7个条目的6跳到1000 [重复]

提问于
浏览
109

这个问题在这里已有答案:

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

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

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

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

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

4 回答

  • 72

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

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

  • 1

    我知道我的回答可能会迟到 . 但我通过在SQL Server 2012中添加启动存储过程以另一种方式解决了这个问题 .

    在主DB中创建以下存储过程 .

    USE [master]
    GO
    SET ANSI_NULLS ON
    GO
    SET QUOTED_IDENTIFIER ON
    GO
    
    ALTER PROCEDURE [dbo].[ResetTableNameIdentityAfterRestart]
    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';
    

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

  • 4

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

  • 15

    虽然跟踪标志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
    

相关问题