Insira um intervalo de números de uma chamada para sp_sequence_get_range
-
26-09-2020 - |
Pergunta
Dado o seguinte código:
CREATE SEQUENCE dbo.NextTestId AS [bigint]
START WITH 10 INCREMENT BY 2 NO CACHE
GO
DECLARE
@variableNumberOfIdsNeeded INT = 7, -- This will change for each call
@FirstSeqNum SQL_VARIANT , @LastSeqNum sql_variant, @SeqIncr sql_variant;
EXEC sys.sp_sequence_get_range @sequence_name = N'dbo.NextTestId',
@range_size = @variableNumberOfIdsNeeded,
@range_first_value = @FirstSeqNum OUTPUT,
@range_last_value = @LastSeqNum OUTPUT,
@sequence_increment = @SeqIncr OUTPUT;
-- The following statement returns the output values
SELECT @FirstSeqNum AS FirstVal, @LastSeqNum AS LastVal, @SeqIncr AS SeqIncrement;
Eu obtenho um resultado assim:
FirstVal LastVal SeqIncrement
------- ------- --------------
38 50 2
Eu gostaria de ter um baseado em conjunto maneira de pegar esses resultados e inserir cada valor (pulando por SeqIncrement) nesta tabela:
DECLARE @newIds TABLE (IdType VARCHAR(100), [NewId] BIGINT)
Então, quando eu terminar, um SELECT * from @newIds
retornaria:
IdType NewId
------- -------
TestId 38
TestId 40
TestId 42
TestId 44
TestId 46
TestId 48
TestId 50
OBSERVAÇÃO:Não quero usar um loop, se possível.Além disso, precisarei obter uma quantidade variável de resultados (este mostra 7, mas mudará a cada chamada).
Acho que pode haver uma aplicação cruzada ou algo parecido que possa fazer isso.Mas não consigo entender.
Solução
Isso deve ser bom para cerca de 2.500 valores (dependendo da versão):
;WITH x(n) AS
(
SELECT TOP (@variableNumberOfIdsNeeded)
(ROW_NUMBER() OVER (ORDER BY number)-1)
* CONVERT(BIGINT, @SeqIncr)
+ CONVERT(BIGINT, @FirstSeqNum)
FROM master.dbo.spt_values
ORDER BY number
)
--INSERT @newIds([NewId])
SELECT n FROM x;
Se você precisar de mais ou estiver preocupado em usar a visualização master.dbo.spt_values
, veja outras técnicas possíveis para gerar conjuntos sem loop aqui: