Вот способ сделать это, используя таблицу для хранения вашего последнего порядкового номера. Хранимый процесс очень прост, большинство вещей там, потому что я ленив и не люблю сюрпризов, если я что-то забуду так ... вот оно:
----- Создать таблицу значений последовательности.
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[SequenceTbl]
(
[CurrentValue] [bigint]
) ON [PRIMARY]
GO
----------------- Создать хранимую процедуру
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE procedure [dbo].[sp_NextInSequence](@SkipCount BigInt = 1)
AS
BEGIN
BEGIN TRANSACTION
DECLARE @NextInSequence BigInt;
IF NOT EXISTS
(
SELECT
CurrentValue
FROM
SequenceTbl
)
INSERT INTO SequenceTbl (CurrentValue) VALUES (0);
SELECT TOP 1
@NextInSequence = ISNULL(CurrentValue, 0) + 1
FROM
SequenceTbl WITH (HoldLock);
UPDATE SequenceTbl WITH (UPDLOCK)
SET CurrentValue = @NextInSequence + (@SkipCount - 1);
COMMIT TRANSACTION
RETURN @NextInSequence
END;
GO
-------- Используйте хранимую процедуру в Sql Manager, чтобы получить тестовое значение.
declare @NextInSequence BigInt
exec @NextInSequence = sp_NextInSequence;
--exec @NextInSequence = sp_NextInSequence <skipcount>;
select NextInSequence = @NextInSequence;
----- Показать текущее значение таблицы.
select * from SequenceTbl;
Проницательный заметит, что для сохраненного процесса есть параметр (необязательный). Это позволяет вызывающему абоненту зарезервировать блок идентификаторов в том случае, если у вызывающего абонента имеется более одной записи, для которой требуется уникальный идентификатор - при использовании SkipCount вызывающему абоненту необходимо сделать только один вызов для любого количества идентификаторов.
Весь блок «IF EXISTS ... INSERT INTO ...» можно удалить, если вы не забыли вставить запись при создании таблицы. Если вы также не забыли вставить эту запись со значением (ваше начальное значение - число, которое никогда не будет использоваться в качестве идентификатора), вы также можете удалить часть выбора ISNULL (...) и просто использовать CurrentValue + 1.
Теперь, прежде чем кто-либо сделает комментарий, пожалуйста, обратите внимание, что я инженер-программист, не DBA! Итак, любая конструктивная критика в отношении использования «Top 1», «With (HoldLock)» и «With (UPDLock)» приветствуется. Я не знаю, насколько хорошо это будет масштабироваться, но пока у меня все в порядке ...