Incremento de identidade da coluna do SQL Server 2012 pulando de 6 para 1000+ na 7ª input

Eu tenho um cenário estranho em que a coluna auto identity int em meu database do SQL Server 2012 não está incrementando corretamente.

Digamos que eu tenha uma tabela que usa uma identidade automática int como uma chave primária, ela está saltando esporadicamente de incrementos, por exemplo:

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

Isso está acontecendo em um número random de tabelas em momentos muito randoms, não pode replicá-lo para encontrar tendências.

Como isso está acontecendo? Existe uma maneira de fazer isso parar?

Isso tudo é perfeitamente normal. Microsoft adicionou sequences no SQL Server 2012, finalmente, eu poderia adicionar e mudou a maneira como as chaves de identidade são geradas. Dê uma olhada aqui para alguma explicação.

Se você quiser ter o comportamento antigo, você pode:

  1. use o sinalizador de rastreamento 272 – isso fará com que um registro de log seja gerado para cada valor de identidade gerado. O desempenho da geração de identidade pode ser afetado ao ativar esse sinalizador de rastreamento.
  2. use um gerador de seqüência com a configuração NO CACHE ( http://msdn.microsoft.com/en-us/library/ff878091.aspx )

Eu sei que minha resposta pode estar atrasada para a festa. Mas eu resolvi de outra maneira, adicionando um procedimento armazenado de boot no SQL Server 2012.

Crie um procedimento armazenado a seguir no database mestre.

 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 

Em seguida, adicione-o ao Start up usando a seguinte syntax.

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

Essa é uma boa ideia se você tiver poucas tabelas. mas se você tiver que fazer por muitas tabelas, esse método ainda funciona, mas não é uma boa ideia.

Tenho o mesmo problema, encontrei o seguinte relatório de bug no SQL Server 2012 Se ainda for relevante, veja as condições que causam o problema – também há algumas soluções (não tente). Failover ou Reiniciar Resultados em Reseed of Identity

Enquanto o sinalizador de rastreamento 272 pode funcionar para muitos, ele definitivamente não funcionará para instalações Sql Server Express hospedadas. Então, criei uma tabela de identidade e uso isso por meio de um gatilho INSTEAD OF. Espero que isso ajude alguém e / ou dê aos outros a oportunidade de melhorar minha solução. A última linha permite retornar a última coluna de identidade adicionada. Como normalmente uso isso para adicionar uma única linha, isso funciona para retornar a identidade de uma única linha inserida.

A tabela de identidade:

 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] 

e o gatilho de inserção:

 -- 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