如何强制生成新的sysdatetime()?

时间:2019-05-20 10:23:40

标签: sql sql-server tsql sql-server-2012

我试图创建一个函数,用于根据来自this solution的时间戳生成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 个答案:

答案 0 :(得分:1)

简短版本:不,那不可能。如果循环足够紧,if ($arrCategoryCurr['parentId'] && $arrCategoryCurr['parentId'] != $arrCategoryCurr['id'] && isset($arrCategories[$arrCategoryCurr['parentId']])) { 将为循环的多次迭代返回相同的值。

长版:

SysDateTime()返回当前日期和时间为SysDateTime
它使用DateTime2(7) win-api函数获取当前日期和时间值。
这意味着,即使它返回的精度为GetSystemTimeAsFileTime(),其精度为100纳秒,但返回值的实际精度取决于运行SQL Server实例的Windows的计算机硬件和版本。

我猜想在一台可以从该win-api函数获得非常准确的结果,但是在SQL中执行慢速循环的计算机上,您可能能够在循环中获得唯一的ID-但是,我无法甚至猜测要获得哪种硬件,Windows版本和常规设置(甚至可能)。

从2012年版本开始,生成不依赖于表插入的唯一bigint值的最佳方法是使用sequence