I have a query to retrieve all the modules and child modules for a page, using a common table expression. Is it possible to use the results from the cte more than once?
From the WITH common_table_expression manual:
Specifies a temporary named result set, known as a common table expression (CTE). This is derived from a simple query and defined within the execution scope of a single SELECT, INSERT, UPDATE, or DELETE statement.
So, no, you can't extend the scope of the CTE beyond the SELECT statement it was defined in. You will have to store the result in a temporary table or table valued variable if you want to use the result more than once.
You will need split child_modules CTE into two CTE's.
The first one containing the first SELECT of the current child_modules CTE, then use a second CTE that builds upon child_modules.
Your final SELECT would then use the third CTE instead of child_modules.
Use like following :
Create FUNCTION [dbo].[fnGetAllData]
(
@UserId int
)
RETURNS TABLE
AS
RETURN
(
WITH UserPRecursive AS
(
SELECT u.userid,u.OverrideID
FROM UserOverride u where OverrideID=@UserId
UNION ALL
SELECT C.userid,C.OverrideID
FROM UserOverride AS C INNER JOIN UserPRecursive AS cr
ON C.OverrideID = cr.userid
)
, UserCRecursive AS
(
SELECT u.userid,u.OverrideID
FROM UserOverride u where UserID=@UserId
UNION ALL
SELECT C.userid,C.OverrideID
FROM UserOverride AS C INNER JOIN UserCRecursive AS cr
ON C.userid = cr.OverrideID
)
SELECT distinct CR1.userid as userId FROM UserPRecursive AS CR1
UNION ALL
SELECT distinct cr2.OverrideID as userId FROM UserCRecursive AS CR2
UNION ALL
select userid from [User] where UserID=@UserId
)