After creating the numbers CTE in my
last post I wanted to go on building my standard auxiliary schema. First of all lets create the schema. Quite simple:
CREATE SCHEMA [Auxiliary]
A
schema in SQL server 2005 is a collection of database entities that form a single namespace.
I now got a place to put auxiliary entities.
First off, I decided to put my Numbers CTE into a table valued function. I wanted to make it a bit flexible by giving the startnumber, endnumber and increment as parameters.
Incidentally this suddenly looked a little bit like the For(i=1; i <=1000; i++) construct in C and C#
CREATE FUNCTION Auxiliary.Numbers
(
@AFrom INT,
@ATo INT,
@AIncrement INT
)
RETURNS @RetNumbers TABLE
(
[Number] int PRIMARY KEY NOT NULL
)
AS
BEGIN
WITH Numbers(n)
AS
(
SELECT @AFrom AS n
UNION ALL
SELECT (n + @AIncrement) AS n
FROM Numbers
WHERE
n < @ATo
)
INSERT @RetNumbers
SELECT n from Numbers
OPTION(MAXRECURSION 0)
RETURN;
END;
To use this to retrieve a list of numbers between 10 and 1000 incremented by 10:
SELECT Number FROM Auxiliary.Numbers(10,1000,10)
This will return:
Number
-----------
10
20
30
...
980
990
1000
(100 row(s) affected)
For a large number of numbers this function is quite slow. An inlined version of this performs much better, but you need to specify the MAXRECURSION hint in the statement using the function:
CREATE FUNCTION Auxiliary.iNumbers
(
@AFrom INT,
@ATo INT,
@AIncrement INT
)
RETURNS TABLE
AS
RETURN(
WITH Numbers(n)
AS
(
SELECT @AFrom AS n
UNION ALL
SELECT (n + @AIncrement) AS n
FROM Numbers
WHERE
n < @ATo
)
SELECT n AS Number from Numbers
)
To use this to retrieve a list of numbers between 10 and 1000 incremented by 10:
SELECT Number FROM Auxiliary.iNumbers(10,1000,10)
If your "table" will return more than 101 numbers (100 recursions):
SELECT Number FROM Auxiliary.iNumbers(1,10000,1)
OPTION(MAXRECURSION 10000)
If you need really many numbers then you definitely should build a permanent numberstable.
Louis Davidson wrote a nice post a about it
here.