我想从序列中获取当前值 - 与序列属性窗口 SQL Server Management Studio 中显示的值相同
我的序列是使用以下语句创建的:
CREATE SEQUENCE [OrderNumberSequence]
as int
START WITH 4000
INCREMENT BY 1
MINVALUE 0
NO MAXVALUE
NO CACHE;
GO
我已经尝试过这个 来自 MSDN 的 SQL – 但结果是每次运行查询时我的数字都会增加 5
DECLARE
@FirstSeqNum sql_variant
, @LastSeqNum sql_variant
, @CycleCount int
, @SeqIncr sql_variant
, @SeqMinVal sql_variant
, @SeqMaxVal sql_variant ;
EXEC sys.sp_sequence_get_range
@sequence_name = N'[OrderNumberSequence]'
, @range_size = 5
, @range_first_value = @FirstSeqNum OUTPUT
, @range_last_value = @LastSeqNum OUTPUT
, @range_cycle_count = @CycleCount OUTPUT
, @sequence_increment = @SeqIncr OUTPUT
, @sequence_min_value = @SeqMinVal OUTPUT
, @sequence_max_value = @SeqMaxVal OUTPUT ;
-- The following statement returns the output values
SELECT
@FirstSeqNum AS FirstVal
, @LastSeqNum AS LastVal
, @CycleCount AS CycleCount
, @SeqIncr AS SeqIncrement
, @SeqMinVal AS MinSeq
, @SeqMaxVal AS MaxSeq ;
有没有一种方法可以在不改变数字的情况下获取值?
您可以从
current_value
中选择sys.sequences
:
SELECT current_value FROM sys.sequences WHERE name = 'OrderNumberSequence' ;
如果你使用 PostgreSQL,你可以使用这个:
SELECT last_value FROM <sequence_name>;
这是一个很老的问题,但是如果您想知道如何获取序列的正确值,即使没有从中获取任何值,您也应该考虑列
last_value_used
。SELECT current_value FROM sys.sequences WHERE name = 'OrderNumberSequence' ;
将返回序列在第一个 next value from ..
之后返回的第一个值。然后,在第一个 next value from
之后,该语句将返回相同的结果!
相反,当从未从序列中获取任何值时,最好使用
NULL
,例如当序列刚刚创建或重新启动时。
表
sys.sequences
有一个 last_value_used
列,当未从序列中获取值或序列刚刚重新启动时,该列为 NULL
。current_value
列报告将使用第一个“next value from
”上的序列的第一个值,并且从那时起将报告“当前实际值”,而last_value_used
列将是NULL
直到您要求第一个值。last_value_used
将始终等于current_value
。
您可以使用此处的示例片段自行测试。
drop sequence if exists dbo.MySequence
go
-- 1. create sequence without touching it
CREATE SEQUENCE [dbo].[MySequence]
AS [int]
START WITH 1
INCREMENT BY 1
MINVALUE 1
MAXVALUE 2147483647
CYCLE
CACHE
GO
-- 2. observe current_value and last_used_value columns (should be current_value = 1, last_used_value = null)
SELECT 'Observe initial state of sequence after creation' msg, current_value, last_used_value FROM sys.sequences WHERE name = 'MySequence'
-- 3. get current value of sequence, based on last_used_value nullable state
declare @CurrentValue sql_variant
SELECT @CurrentValue = CASE WHEN last_used_value IS NULL THEN NULL ELSE current_value END
FROM sys.sequences WHERE name = 'MySequence'
select 'Current actual value' msg, @CurrentValue current_value -- should be null
-- 4. get next value from sequence
select 'Get first value from sequence' msg, next value for dbo.MySequence value -- should be 1
-- 5. observe current_value and last_used_value columns (should be current_value = 1, last_used_value = 1)
SELECT 'Observe state of sequence after getting first value' msg, current_value, last_used_value FROM sys.sequences WHERE name = 'MySequence'
-- 6. get current value of sequence, based on last_used_value nullable state
SELECT @CurrentValue = CASE WHEN last_used_value IS NULL THEN NULL ELSE current_value END
FROM sys.sequences WHERE name = 'MySequence'
select 'Current actual value' msg, @CurrentValue current_value -- should be 1
-- 7. get another value from seqeunce
select 'Get second value from sequence' msg, next value for dbo.MySequence value -- should be 2
-- 8. observe current_value and last_used_value columns (should be current_value = 2, last_used_value = 2)
SELECT 'Observe state of sequence after getting second value' msg, current_value, last_used_value FROM sys.sequences WHERE name = 'MySequence'
-- 9. get current value of sequence, based on last_used_value nullable state
SELECT @CurrentValue = CASE WHEN last_used_value IS NULL THEN NULL ELSE current_value END
FROM sys.sequences WHERE name = 'MySequence'
select 'Current actual value' msg, @CurrentValue current_value -- should be 2