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