SQL Server 如何确定序列中的下一个值?

Posted

技术标签:

【中文标题】SQL Server 如何确定序列中的下一个值?【英文标题】:How does SQL Server detmine the next value in a sequence? 【发布时间】:2018-04-28 16:49:05 【问题描述】:

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

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

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

【问题讨论】:

【参考方案1】:

那么有谁知道我的国旗理论是否正确,如果正确,在哪里? 此标志驻留(即它是否在可访问的系统视图中)。

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

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

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

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

0x030000000000000002000000000000000000000000000080FFFFFFFFFFFFFF7F090000000000000000

这是运行ALTER SEQUENCE abc RESTART WITH 9;后的样子

0x090000000000000002000000000000000000000000000080FFFFFFFFFFFFFF7F090000000000000001

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

但是你为什么在乎呢?任何计算下一个值的尝试都将充满竞争条件和无法保证的行为。您应该在需要时致电NEXT VALUE 并接受它为您提供的东西。

【讨论】:

测试总是会引发有趣的场景,这不适用于生产环境。我为什么在乎?只是为了更好地理解 SQL Server 的工作原理而进行自我改进。感谢您为我指明正确的方向。

以上是关于SQL Server 如何确定序列中的下一个值?的主要内容,如果未能解决你的问题,请参考以下文章

如何确定 SQL Server 2012 中是不是存在序列?

如何根据 SQL 中的时间戳查找特定事件的下一个序列?

将 Oracle 序列重置为现有列中的下一个值的最佳方法?

sql 获取序列的下一个值

如何使用 H2 嵌入式数据库获取序列中的下一个值?

如何在 SQL Server 中的 OR 条件中确定优先级