Мне приходилось сталкиваться с этим несколько лет назад, поэтому я нашел самый быстрый / простой способ, если в вашей базе данных есть таблица с большим количеством записей, чем нужно считать.
Прежде всего, несмотря на предложения, вам не нужно "создавать" таблицу записей ... все, что вам нужно, это "ЛЮБАЯ" таблица, в которой уже есть записи. Пока в таблице больше записей, чем нужно посчитать, значит, вы хороши.
SELECT top (5) ROW_NUMBER() OVER(Order by [Primary_Key] desc) AS Integer
FROM SOME_TABLE --that has more than 5 rows.
ТАКЖЕ это элегантный (математический) способ. Там, где у вас нет большой таблицы в базе данных.
Использовать рекурсию Split, это позволяет генерировать таблицу, содержащую до 2 ^ n-1 целых чисел, где n - ваш предел рекурсии. Кроме того, он полностью параметризован, поэтому его легко можно вставить в функцию
DECLARE @n int, @cnt int;
set @cnt = 5;
SET @n = LOG(@cnt)/LOG(2) +1; --use change of base to find LOG base 2
WITH Num AS (
SELECT @n [Value]
UNION ALL
SELECT [Value] - 1
FROM Num
WHERE [Value] > 1
UNION ALL
SELECT [Value] - 1
FROM Num
WHERE [Value] > 1
)
SELECT * from (
SELECT ROW_NUMBER() OVER(Order by Value asc) AS [Integer]
FROM Num
)i
where [Integer] <= @cnt
Единственным недостатком этого является то, что он может генерировать вдвое больше записей, чем необходимо во время рекурсии, поэтому он может привести к большим накладным расходам, чем встроенная рекурсия. НО из-за этого полностью избегает предела рекурсии. (вам никогда не нужно перечислять первые 2 ^ 100-1 целых чисел.) (также я просто собираюсь предсказать, что у вас нет компьютера с таким большим количеством места на жестком диске.)
Этот недостаток - то, почему я создал следующую функцию. Которая использует ту же технику удвоения, что и рекурсия с разделением, но внутри цикла while. И в последний раз, когда он запускается, он только ставит необходимые записи, а не удваивает. Эта функция также позволяет вам указать диапазон и возвращает все числа в этом диапазоне с индексом этих чисел на основе 0. Раньше я считал этот столбец с нулевой базой бесполезным артефактом вычислений, но очень полезно иметь диапазон и его индекс в одной строке.
create function [dbo].[fn_Integers]
(
@Min_Integer int = 1
,@Max_Integer int
)
RETURNS @retTable TABLE
([BASE] int identity(0,1)
,[INTEGER] int)
AS
BEGIN
Declare @RANGE int
SET @RANGE = @Max_Integer-@Min_Integer
insert into @retTable
select NULL --initial value for recursion
While ((SELECT MAX([BASE]) FROM @retTable r) < @RANGE )
BEGIN
INSERT into @retTable
select [INTEGER] from @retTable r
where [BASE] < (SELECT @RANGE - MAX([BASE]) FROM @retTable r)
END
Update @retTable set
[INTEGER] = [BASE] + @Min_Integer
RETURN
END
GO
это может делать около 50000 целых чисел в секунду (на моей рабочей станции)
и вывод выглядит как
SELECT * FROM [fn_Integers](18,50000)
BASE INTEGER
-----------------
0 18
1 19
2 20
...
49982 50000