简体   繁体   English

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

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

If you alter a sequence to restart with a value exactly the same as its current value the next value will be the one specified as opposed to the current value plus the increment. 如果更改序列以与当前值完全相同的值重新启动,则下一个值将是指定的值,而不是当前值加上增量。 All very well and good but how does the SQL Server engine determine to use the current value rather than adding the increment? 一切都很好,但是SQL Server引擎如何确定使用当前值而不是增加增量? I am assuming there is a flag somewhere to indicate the current status. 我假设某处有一个标志来指示当前状态。

Looking at the sys.sequences view before and after this series of events I have only observed a change in the objects modify_date and start_value columns after the ALTER SEQUENCE statement. 查看这一系列事件之前和之后的sys.sequences视图,我仅观察到ALTER SEQUENCE语句之后的对象Modify_date和start_value列中的变化。 Getting the NEXT VALUE only changes the current_value column after the second NEXT VALUE is selected either from the sequence being initially created or an ALTER SEQUENCE...RESTART statement. 从初始创建的序列或ALTER SEQUENCE ... RESTART语句中选择第二个NEXT VALUE后,获取NEXT VALUE只会更改current_value列。

Here is an example to demonstrate (modify_date column is just shown as a time): 这是一个示例演示(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

Sequence created and the current_value column shows the next value to be used in the sequence. 创建了序列,并且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

The current_value is now showing the last value used ie The next value will be the current value plus the increment. 现在,current_value显示使用的最后一个值,即下一个值将是当前值加上增量。

ALTER SEQUENCE abc RESTART WITH 9;

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

So the date and start value have changed and I am guessing some flag somewhere has been set to indicate this sequence now needs to start with the current value. 因此,日期和起始值已更改,我猜想在某处已设置一些标志,以指示此序列现在需要从当前值开始。

SELECT NEXT VALUE FOR abc;  -- 9

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

No changes observed in the sys.sequences view. 在sys.sequences视图中未观察到任何变化。

SELECT NEXT VALUE FOR abc;  -- 11

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

The sequence now continues as expected with only the current_value changing in the view. 现在,该序列将按预期继续,仅在视图中更改current_value。

So does anyone know if my flag theory is correct and, if it is, where this flag resides (ie Is it in a accessible system view). 谁也知道我的标志理论是否正确,以及是否存在该标志所在的位置(即它是否在可访问的系统视图中)。

So does anyone know if my flag theory is correct and, if it is, where this flag resides (ie Is it in a accessible system view). 谁也知道我的标志理论是否正确,以及是否存在该标志所在的位置(即它是否在可访问的系统视图中)。

Yes - looks like this is probably correct. 是的-看起来这可能是正确的。 But not in a very accessible system view. 但不是在非常易于访问的系统视图中。

If you connect via the DAC you can run 如果通过DAC连接,则可以运行

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

Here is how it looks after reaching 9 organically after incrementing the sequence 4 times (and setting the database offline to ensure all cached changes written to disc). 这是将序列递增4次后自然达到9(并且将数据库设置为脱机以确保将所有缓存的更改写入磁盘后)的外观。

0x030000000000000002000000000000000000000000000080FFFFFFFFFFFFFF7F090000000000000000

And here's how it looks after running ALTER SEQUENCE abc RESTART WITH 9; 这是运行ALTER SEQUENCE abc RESTART WITH 9;之后的外观ALTER SEQUENCE abc RESTART WITH 9;

0x090000000000000002000000000000000000000000000080FFFFFFFFFFFFFF7F090000000000000001

I imagine the change at the very beginning (of 03 to 09 ) is because the START WITH has now changed. 我想从一开始(从0309 )的更改是因为START WITH现在已经更改。 And the final byte has the flag you seek. 最后一个字节具有您要查找的标志。

But why do you care? 但是你为什么在乎呢? Any attempt to calculate the next value will be fraught with race conditions and un-guaranteed behaviour. 任何试图计算下一个值的尝试都会充满竞争条件和无法保证的行为。 You should just call NEXT VALUE when you need it and take what it gives you. 您只需要在需要时调用NEXT VALUE ,然后使用该值即可。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM