I'm emulating PostgreSQL style generate_series()
table-valued functions in SQL Server as such:
CREATE FUNCTION generate_series(@d1 DATE, @d2 DATE)
RETURNS TABLE AS
RETURN
-- Ignore implementation (returning a single DATE column) for this question
This can now be used as expected:
SELECT *
FROM generate_series(
CAST ('2005-07-01' AS DATE),
CAST ('2005-07-31' AS DATE)
) t
Now I'd like to use derived column list syntax to rename columns along with the table as such:
SELECT *
FROM generate_series(
CAST ('2005-07-01' AS DATE),
CAST ('2005-07-31' AS DATE)
) t(col)
Which is producing this error:
Msg 195, Level 15, State 15, Line 5
'generate_series' is not a recognized function name.
... whereas this syntax (qualifying the function) ...
SELECT *
FROM dbo.generate_series(
CAST ('2005-07-01' AS DATE),
CAST ('2005-07-31' AS DATE)
) t(col)
... is producing this error:
Msg 317, Level 16, State 1, Line 5
Table-valued function 'generate_series' cannot have a column alias.
This syntax is perfectly valid in my opinion. It works this way in PostgreSQL, standard SQL, and in "ordinary" T-SQL as well, e.g.:
SELECT *
FROM (
VALUES (1),(2)
) t(col)
What am I doing wrong? How could I achieve this? (I'm aware of the possibility of emulating this, but I'd like to really use derived column list syntax).
I'm using SQL Server Express 2014
I would guess it is because although dbo.generate_series is a function it is returning a table. so:
Wouldn't work
but
Would work
So in other words Derived Columns list will work with a derived table but not when the table is NOT derived?
I would assume the preferred syntax which I am sure you know is to use column aliases rather than derived column list.
You can't add a column alias in this case. This is not using a table valued constructor, it is returning from a table valued function. Just drop the column alias and it is fine.
FWIW, I would suggest using a tally table instead of recursive cte in your function. If your date range is lengthy the performance is going to suffer because you are effectively using a rcte to count. If you examine the execution plan it is the same thing as a while loop. Jeff Moden has an awesome article discussing this in great detail. http://www.sqlservercentral.com/articles/T-SQL/74118/
--EDIT--
To create an alias can you not simply add an alias?
The relevant part of the from clause is here.
column_alias
is only supported for derived tables and@variable.function_call
So, at least for the time being, you would need to wrap the
user_defined_function
call. e.g. in a derived table or CTE to alias the columns.