SQL 服务器如何确定序列中的下一个值?

How does SQL Server detmine the next value in a sequence?

如果您更改序列以使用与其当前值完全相同的值重新启动,则下一个值将是指定的值,而不是当前值加上增量。一切都很好,但是 SQL 服务器引擎如何确定使用当前值而不是添加增量?我假设某处有一个标志来指示当前状态。

查看这一系列事件前后的 sys.sequences 视图,我只观察到对象 modify_date 和 start_value 列在 ALTER SEQUENCE 语句之后发生了变化。在从最初创建的序列或 ALTER SEQUENCE...RESTART 语句中选择第二个 NEXT VALUE 后,获取 NEXT VALUE 只会更改 current_value 列。

这里举例说明(modify_date列只显示时间):

CREATE SEQUENCE abc START WITH 3 INCREMENT BY 2;

modify_date      current_value increment   start_value
---------------- ------------- ----------- -----------
17:39:57.04      3             2           3

序列已创建,current_value 列显示序列中要使用的下一个值。

SELECT NEXT VALUE FOR abc;  -- 3
SELECT NEXT VALUE FOR abc;  -- 5
SELECT NEXT VALUE FOR abc;  -- 7
SELECT NEXT VALUE FOR abc;  -- 9

modify_date      current_value increment   start_value
---------------- ------------- ----------- -----------
17:39:57.04      9             2           3

current_value 现在显示上次使用的值,即下一个值将是当前值加上增量。

ALTER SEQUENCE abc RESTART WITH 9;

modify_date      current_value increment   start_value
---------------- ------------- ----------- -----------
17:40:17.42      9             2           9

所以日期和开始值已经改变,我猜某处设置了一些标志来指示这个序列现在需要从当前值开始。

SELECT NEXT VALUE FOR abc;  -- 9

modify_date      current_value increment   start_value
---------------- ------------- ----------- -----------
17:40:17.42      9             2           9

sys.sequences 视图中未观察到任何变化。

SELECT NEXT VALUE FOR abc;  -- 11

modify_date      current_value increment   start_value
---------------- ------------- ----------- -----------
17:40:17.42      11            2           9

序列现在按预期继续,只有 current_value 视图发生变化。

所以有谁知道我的标志理论是否正确,如果正确,这个标志所在的位置(即它是否在可访问的系统视图中)。

So does anyone know if my flag theory is correct and, if it is, where this flag resides (i.e. Is it in a accessible system view).

是的 - 看起来这可能是正确的。但不是在非常易于访问的系统视图中。

如果您通过 DAC 连接,您可以运行

SELECT value
FROM   sys.sysobjvalues
WHERE  objid = OBJECT_ID('abc');

这是在将序列递增 4 次后有机地达到 9 后的样子(并将数据库设置为离线以确保将所有缓存的更改写入磁盘)。

0x030000000000000002000000000000000000000000000080FFFFFFFFFFFFFF7F090000000000000000

这是 运行ning ALTER SEQUENCE abc RESTART WITH 9;

之后的样子
0x090000000000000002000000000000000000000000000080FFFFFFFFFFFFFF7F090000000000000001

我想象一开始的变化(0309)是因为 START WITH 现在已经改变了。最后一个字节有你要找的标志。

但你为什么要关心?任何计算下一个值的尝试都将充满竞争条件和无法保证的行为。你应该在需要的时候打电话给 NEXT VALUE 并接受它给你的东西。