我有一个查询,使用公用表表达式检索页面的所有模块和子模块。是否可以多次使用cte的结果?
例如
WITH top_level_modules (
[AppContentModuleID]
,[SortIndex]
,[ContentHolderName]
,[OwnerType]
,[AppContentModuleGuid]
,[parent_AppContentModuleID]
,[ModuleID]
,[RenderIDTag]
,[WrapperType]
,[Level]
)
AS
(
SELECT amcp.[AppContentModuleID]
,amcp.[SortIndex]
,amcp.[ContentHolderName]
,1
,amc.[AppContentModuleGuid]
,amc.[parent_AppContentModuleID]
,amc.[ModuleID]
,amc.[RenderIDTag]
,amc.[WrapperType]
,0 AS [Level]
FROM [dbo].[application_module_content_page] amcp
INNER JOIN [dbo].[application_module_content] amc on amcp.[AppContentModuleID] = amc.[AppContentModuleID]
WHERE amcp.[PageID] = @PageID
UNION
SELECT amcm.[AppContentModuleID]
,amcm.[SortIndex]
,amcm.[ContentHolderName]
,2
,amc.[AppContentModuleGuid]
,amc.[parent_AppContentModuleID]
,amc.[ModuleID]
,amc.[RenderIDTag]
,amc.[WrapperType]
,0
FROM [dbo].[application_module_content_masterpage] amcm
INNER JOIN [dbo].[application_module_content] amc on amcm.[AppContentModuleID] = amc.[AppContentModuleID]
WHERE amcm.[AppMasterPageID] = @MasterPageID
),
child_modules AS
(
SELECT tlm.[AppContentModuleID]
,tlm.[SortIndex]
,tlm.[ContentHolderName]
,tlm.[OwnerType]
,tlm.[AppContentModuleGuid]
,tlm.[parent_AppContentModuleID]
,tlm.[ModuleID]
,tlm.[RenderIDTag]
,tlm.[WrapperType]
,tlm.[Level]
FROM top_level_modules tlm
UNION ALL
SELECT
amc.[AppContentModuleID]
,CASE WHEN amc.[SortIndex] IS NULL THEN tlm.[SortIndex] ELSE amc.[SortIndex] END
,null
,3
,amc.[AppContentModuleGuid]
,amc.[parent_AppContentModuleID]
,amc.[ModuleID]
,amc.[RenderIDTag]
,amc.[WrapperType]
,[Level] + 1 AS [Level]
FROM [dbo].[application_module_content] amc
INNER JOIN child_modules tlm on tlm.[AppContentModuleID] = amc.[parent_AppContentModuleID]
)
SELECT *
FROM child_modules cm
ORDER BY cm.[OwnerType]
, cm.[Level]
, cm.[SortIndex]
SELECT apcs.[StyleType]
,apcs.[StyleName]
,apcs.[StyleValue]
FROM child_modules cm
INNER JOIN dbo.[application_module_content_style] apcs
on cm.AppContentMdouleID = apcs.AppContentMdouleID
第一个选择有效,但第二个选择会引发错误“无效对象名称'child_modules'。”
答案 0 :(得分:10)
来自the WITH common_table_expression
manual:
指定临时命名结果集,称为公用表表达式(CTE)。这是从一个简单的查询和在单个 SELECT,INSERT,UPDATE或DELETE语句的执行范围内定义的。
所以,不,你不能将CTE的范围扩展到它定义的SELECT语句之外。如果你想要将结果存储在临时表中,那么你必须将结果存储在临时表或表值变量中一次。
答案 1 :(得分:2)
您需要将child_modules CTE拆分为两个CTE。
第一个包含当前child_modules CTE的第一个SELECT,然后使用第二个基于child_modules的CTE。
然后,您的最终SELECT将使用第三个CTE而不是child_modules。
答案 2 :(得分:0)
使用如下:
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
)