SQL Server 2012 приращение идентификатора столбца прыгает с 6 до 1000+ на 7-й записи [дубликат]
этот вопрос уже есть ответ здесь:
У меня есть странный сценарий, в котором столбец auto identity int в моей базе данных SQL Server 2012 не увеличивается должным образом.
скажем, у меня есть таблица, которая использует int auto identity в качестве первичный ключ это спорадически пропуская приращения, например:
1, Два, Три, Четыре, Пять, Одна тысяча четыре, 1005
Это происходит на случайном количестве таблиц в очень случайные моменты времени, не может повторить его, чтобы найти какие-либо тенденции.
Как это происходит? Есть ли способ остановить это?
4 ответа:
Это все совершенно нормально. Microsoft добавила
sequences
в SQL Server 2012, наконец, я мог бы добавить и изменить способ создания ключей идентификации. Посмотри здесь для некоторого объяснения.Если вы хотите иметь старое поведение, вы можете:
- использовать флаг трассировки 272-это приведет к созданию записи журнала для каждого сгенерированного значения идентификатора. Включение этой трассировки может повлиять на производительность генерации идентификаторов флаг.
- используйте генератор последовательностей с параметром no CACHE (http://msdn.microsoft.com/en-us/library/ff878091.aspx)
Я знаю, что мой ответ может опоздать на вечеринку. Но я решил по-другому, добавив хранимую процедуру запуска в SQL Server 2012.
создайте следующую хранимую процедуру в главной БД.
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';
Это хорошая идея, если у вас есть несколько таблиц. но если вам нужно сделать много таблиц, этот способ все еще работает, но не очень хорошая идея.
получил ту же проблему, нашел следующий отчет об ошибке в SQL Server 2012 Если все еще актуальны условия, которые вызывают проблему-есть некоторые обходные пути там, а также (не пробовал, хотя). отказоустойчивость или перезапуск приводит к повторному заполнению идентификатора
хотя флаг трассировки 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