SQL Server为序列获取多个next值

SQL Server为序列获取多个next值,sql,sql-server,tsql-sequence,Sql,Sql Server,Tsql Sequence,在SQL Server中,您可以从如下序列中选择下一个值: select next value for MY_SEQ select top(10) next value for MY_SEQ 如果不抑制要从中选择的表,则将为每一行输出下一个值: select next value for MY_SEQ from MY_TABLE [2020-09-08 15:47:34] 350 rows retrieved starting from 1 in 102 ms (execution: 6

在SQL Server中,您可以从如下序列中选择下一个值:

select next value for MY_SEQ
select top(10) next value for MY_SEQ
如果不抑制要从中选择的表,则将为每一行输出下一个值:

select next value for MY_SEQ 
from MY_TABLE

[2020-09-08 15:47:34] 350 rows retrieved starting from 1 in 102 ms (execution: 62 ms, fetching: 40 ms)
如何为序列选择下一个
n

在Oracle中,这看起来是这样的:

select MY_SEQ.nextval
from (
         select level
         from dual
         connect by level < 10
     )
但结果是:

[S0001][11739]如果已设置ROWCOUNT选项,或者查询包含TOP或OFFSET,则无法使用函数的下一个值


我想我可以创建一个包含
n
行的临时表并从中进行选择,但这不是一个特别优雅的解决方案。

您可以在获取序列值之前提取正确的行数

DECLARE @N INT = 100;

SELECT next value FOR MY_SEQ 
FROM (
    SELECT 1 X
    FROM FN_NUMBERS(@N)
) X


CREATE FUNCTION [dbo].[FN_NUMBERS](
     @MAX INT
)
RETURNS @N TABLE (N INT NOT NULL PRIMARY KEY)  
BEGIN
     WITH
       Pass0 as (select '1' as C union all select '1'),       --2 rows
       Pass1 as (select '1' as C from Pass0 as A, Pass0 as B),--4 rows
       Pass2 as (select '1' as C from Pass1 as A, Pass1 as B),--16 rows
       Pass3 as (select '1' as C from Pass2 as A, Pass2 as B),--256 rows
       Pass4 as (select TOP (@MAX) '1' as C from Pass3 as A, Pass3 as B)    --65536 rows
       ,Tally as (select TOP (@MAX) '1' as C from Pass4 as A, Pass2 as B, Pass1 as C)  --4194304 rows
       --,Tally as (select TOP (@MAX) '1' as C from Pass4 as A, Pass3 as B)               --16777216 rows
       --,Tally as (select TOP (@MAX) '1' as C from Pass4 as A, Pass4 as B)               --4294836225 rows
     INSERT INTO @N
     SELECT TOP (@MAX) ROW_NUMBER() OVER(ORDER BY C) AS N
     FROM Tally
     RETURN
END
您可以使用
sys.objects

SELECT next value FOR MY_SEQ 
FROM (
    SELECT TOP (@N) 1 X
    FROM sys.objects o1, sys.objects o2, sys.objects o3
) X

我想您正在寻找系统存储过程“sp\u sequence\u get\u range”

要从序列中获得接下来的10个值,应该是这样的

DECLARE @range_first_value_output sql_variant ;  
 
EXEC sys.sp_sequence_get_range  
@sequence_name = N'MY_SEQ'  
, @range_size = 10  
, @range_first_value = @range_first_value_output OUTPUT ;  
 
SELECT @range_first_value_output AS FirstNumber;  

为什么不直接用下一个值填充一个表变量呢

declare @next_values table (next_value int)
declare @i int = 1

while @i <= 10 
begin
  insert into @next_values (next_value)
              select next value for MY_SEQ from MY_TABLE

  set @i = @i + 1
end

-- We return those values 
select * from @next_values
declare@next_值表(next_值int)
声明@i int=1

虽然@i因此我需要一个表,虽然它保证有我需要的行数,但它看起来并不优雅。使用计数表带有
FN\u numbersr
函数的选项似乎可以工作,但是对于手头的问题来说似乎有点过于复杂使用
sys.objects
的解决方案似乎工作得很好,而且它应该在大部分时间都能工作,但它仍然看起来相当粗糙。如果您的数据库中总是有一个FN_数字,您将经常使用它。但是你可以简单地多次使用sys.objects来获得相同的结果这似乎仍然只返回一个值我无法想象手动选择查询的性能特别好这不是一个光标,只是一个循环,我严重怀疑,从循环而不是选择调用n次
下一个值
是否会有很大不同。您仍然需要对该伪函数进行相同的n次调用。