Как форсировать генерацию нового sysdatetime ()? - PullRequest
0 голосов
/ 20 мая 2019

Я попытался создать функцию для генерации bigint UID на основе отметки времени из этого решения . Хотя точность должна быть достаточной, чтобы избежать коллизий, сервер, очевидно, не измеряет datetime2, возвращаемое sysdatetime() при каждом вызове. В цикле я могу сгенерировать десятки идентичных UID, прежде чем произойдет изменение. Я не уверен точно, как это работает внутри, но есть ли способ заставить генерацию нового datetime2 с каждым вызовом?

create function [func].GenerateBigIntID()
returns bigint
as
begin
  declare @Binary binary(9) = cast(reverse(cast(sysdatetime() as binary(9))) as binary(9)) 
  return(select cast(substring(@Binary, 1, 3) as bigint) * 864000000000 + cast(substring(@Binary, 4, 5) as bigint))
end

1 Ответ

1 голос
/ 20 мая 2019

Короткая версия: нет, это невозможно.Если цикл достаточно плотный, SysDateTime вернет одно и то же значение для более чем одной итерации цикла.

Длинная версия:

SysDateTime() возвращаеттекущая дата и время в виде DateTime2(7).
. Получает текущие значения даты и времени, используя GetSystemTimeAsFileTime() функцию win-api.
Это означает, что даже если он возвращает DateTime2 с точностью до 100 наносекунд, Фактическая точность возвращаемого значения зависит от аппаратного обеспечения компьютера и версии Windows, на которой работает экземпляр SQL Server.

Я предполагаю, что на компьютере, который может получить очень точные результаты от этого выигрыша-api и, тем не менее, выполнять медленные циклы в SQL, вы можете получить уникальные идентификаторы в цикле. Однако я даже не мог догадаться, какое оборудование, версия Windows и общие настройки вам понадобятся (или, если это вообще возможно).

Начиная с версии 2012 года, лучший способ создать уникальное значение bigint, не зависящее от вставки в таблицу, - это использовать sequence.

...