sql 视图中的递归 cte 无法正常工作
sql recursive cte in view not work fine
我创建了一个 CTE 查询,它在存储过程中运行良好,当我在查询编辑器中执行时(使用 where 语句)
但是当我尝试创建与 View 相同的视图时(没有 where 语句)。
并使用 where 语句执行此操作,我得到的数据不是递归的。
我没有看到错误。
这是 SP 和查询编辑器中的查询,效果很好。 (SP中的Guid作为参数)
WITH recursiveTable(ParentApplicationRoleId, ChildApplicationRoleId)
AS
(
SELECT ParentApplicationRoleId, ChildApplicationRoleId
FROM ApplicationRoleParentChild
WHERE ParentApplicationRoleId = '69BCC94B-2884-4270-B39E-A09669C1D658'
UNION ALL
SELECT ApplicationRoleParentChild.ParentApplicationRoleId, ApplicationRoleParentChild.ChildApplicationRoleId
FROM ApplicationRoleParentChild
INNER JOIN recursiveTable ON ApplicationRoleParentChild.ParentApplicationRoleId = recursiveTable.ChildApplicationRoleId
)
/* Get all Childelements (from recursive Table) and add the ParentRoleId to this List */
SELECT ApplicationRole.Name AS RoleName
FROM recursiveTable
INNER JOIN ApplicationRole ON ApplicationRole.ApplicationRoleId = recursiveTable.ChildApplicationRoleId
UNION
SELECT Name AS RoleName FROM ApplicationRole WHERE ApplicationRoleId = '69BCC94B-2884-4270-B39E-A09669C1D658'
OPTION(MAXRECURSION 32767)
结果我得到 Result Image
View 需要所有 ApplicationRoles(包括所有 Childroles)并且未经过滤,因为我将在调用 View 时使用过滤器。
我如何更改它在没有 where 语句的情况下工作的 CTE?
我以这个为例。但它 returns 只是 'Administrator' 的直接子元素
我也从 Childs 中搜索 Child。
WITH recursiveTable(ParentApplicationRoleId, ChildApplicationRoleId)
AS
(
SELECT ParentApplicationRoleId, ChildApplicationRoleId
FROM ApplicationRoleParentChild
UNION ALL
SELECT ApplicationRoleParentChild.ParentApplicationRoleId, ApplicationRoleParentChild.ChildApplicationRoleId
FROM ApplicationRoleParentChild
INNER JOIN recursiveTable ON ApplicationRoleParentChild.ParentApplicationRoleId = recursiveTable.ChildApplicationRoleId
)
/* Get all Childelements (from recursive Table) and add the ParentRoleId to this List */
SELECT ApplicationRole.Name AS ChildRoleName, Parent.Name AS ParentRoleName
FROM recursiveTable
INNER JOIN ApplicationRole ON ApplicationRole.ApplicationRoleId = recursiveTable.ChildApplicationRoleId
INNER JOIN ApplicationRole as Parent ON Parent.ApplicationRoleId = recursiveTable.ParentApplicationRoleId
/*The Query-Filter when i call the View: Like SELECT * FROM View WHERE Parent.Name = 'Administrator'
Expected Returns: Role1-10, Departement1-3 and Administrator
Current Returns: Only direct Childs (Role2,7,8, Departement1,3)
Departement2 is Child of Departement1
And some other Roles are in one of the Departements or roles
*/
表格:
ApplicationRole(所有角色)
ApplicationRoleParentChild(所有父子关系)(具有 FK Parent 和 FK Child 角色)
我希望有人能帮助我。
谢谢
yor where
子句过滤所有记录。和更深层次的记录没有直接的 parent 管理员。
要按它过滤,您可以将顶级记录名称存储为 cte
中的列
WITH recursiveTable(ParentApplicationRoleId, ChildApplicationRoleId, TopLevelName)
AS
(
SELECT ParentApplicationRoleId, ChildApplicationRoleId, Name
FROM ApplicationRoleParentChild
UNION ALL
SELECT ApplicationRoleParentChild.ParentApplicationRoleId, ApplicationRoleParentChild.ChildApplicationRoleId
, recursiveTable.TopLevelName
FROM ApplicationRoleParentChild
INNER JOIN recursiveTable ON ApplicationRoleParentChild.ParentApplicationRoleId = recursiveTable.ChildApplicationRoleId
)
或者您甚至可以构建 child
的完整路径
WITH recursiveTable(ParentApplicationRoleId, ChildApplicationRoleId, TopLevelName)
AS
(
SELECT ParentApplicationRoleId, ChildApplicationRoleId, cast(Name as varchar(1000))
FROM ApplicationRoleParentChild
UNION ALL
SELECT ApplicationRoleParentChild.ParentApplicationRoleId, ApplicationRoleParentChild.ChildApplicationRoleId
, left(recursiveTable.TopLevelName + '/' + name, 1000)
FROM ApplicationRoleParentChild
INNER JOIN recursiveTable ON ApplicationRoleParentChild.ParentApplicationRoleId = recursiveTable.ChildApplicationRoleId
)
然后像 where Parent.TopLevelName like '%Administrator%'
一样过滤
更新
如通知
Ivan Starostin 在他的评论中
如果您不想将每条记录都作为顶级来获得所有层次结构的组合。
您必须为 cte 中的第一个 select 添加 where
子句以定义顶级节点。
类似于 ParentApplicationRoleId is NULL
或 ParentApplicationRoleId = ''
我创建了一个 CTE 查询,它在存储过程中运行良好,当我在查询编辑器中执行时(使用 where 语句)
但是当我尝试创建与 View 相同的视图时(没有 where 语句)。 并使用 where 语句执行此操作,我得到的数据不是递归的。 我没有看到错误。
这是 SP 和查询编辑器中的查询,效果很好。 (SP中的Guid作为参数)
WITH recursiveTable(ParentApplicationRoleId, ChildApplicationRoleId)
AS
(
SELECT ParentApplicationRoleId, ChildApplicationRoleId
FROM ApplicationRoleParentChild
WHERE ParentApplicationRoleId = '69BCC94B-2884-4270-B39E-A09669C1D658'
UNION ALL
SELECT ApplicationRoleParentChild.ParentApplicationRoleId, ApplicationRoleParentChild.ChildApplicationRoleId
FROM ApplicationRoleParentChild
INNER JOIN recursiveTable ON ApplicationRoleParentChild.ParentApplicationRoleId = recursiveTable.ChildApplicationRoleId
)
/* Get all Childelements (from recursive Table) and add the ParentRoleId to this List */
SELECT ApplicationRole.Name AS RoleName
FROM recursiveTable
INNER JOIN ApplicationRole ON ApplicationRole.ApplicationRoleId = recursiveTable.ChildApplicationRoleId
UNION
SELECT Name AS RoleName FROM ApplicationRole WHERE ApplicationRoleId = '69BCC94B-2884-4270-B39E-A09669C1D658'
OPTION(MAXRECURSION 32767)
结果我得到 Result Image
View 需要所有 ApplicationRoles(包括所有 Childroles)并且未经过滤,因为我将在调用 View 时使用过滤器。
我如何更改它在没有 where 语句的情况下工作的 CTE?
我以这个为例。但它 returns 只是 'Administrator' 的直接子元素 我也从 Childs 中搜索 Child。
WITH recursiveTable(ParentApplicationRoleId, ChildApplicationRoleId)
AS
(
SELECT ParentApplicationRoleId, ChildApplicationRoleId
FROM ApplicationRoleParentChild
UNION ALL
SELECT ApplicationRoleParentChild.ParentApplicationRoleId, ApplicationRoleParentChild.ChildApplicationRoleId
FROM ApplicationRoleParentChild
INNER JOIN recursiveTable ON ApplicationRoleParentChild.ParentApplicationRoleId = recursiveTable.ChildApplicationRoleId
)
/* Get all Childelements (from recursive Table) and add the ParentRoleId to this List */
SELECT ApplicationRole.Name AS ChildRoleName, Parent.Name AS ParentRoleName
FROM recursiveTable
INNER JOIN ApplicationRole ON ApplicationRole.ApplicationRoleId = recursiveTable.ChildApplicationRoleId
INNER JOIN ApplicationRole as Parent ON Parent.ApplicationRoleId = recursiveTable.ParentApplicationRoleId
/*The Query-Filter when i call the View: Like SELECT * FROM View WHERE Parent.Name = 'Administrator'
Expected Returns: Role1-10, Departement1-3 and Administrator
Current Returns: Only direct Childs (Role2,7,8, Departement1,3)
Departement2 is Child of Departement1
And some other Roles are in one of the Departements or roles
*/
表格: ApplicationRole(所有角色) ApplicationRoleParentChild(所有父子关系)(具有 FK Parent 和 FK Child 角色)
我希望有人能帮助我。
谢谢
yor where
子句过滤所有记录。和更深层次的记录没有直接的 parent 管理员。
要按它过滤,您可以将顶级记录名称存储为 cte
WITH recursiveTable(ParentApplicationRoleId, ChildApplicationRoleId, TopLevelName)
AS
(
SELECT ParentApplicationRoleId, ChildApplicationRoleId, Name
FROM ApplicationRoleParentChild
UNION ALL
SELECT ApplicationRoleParentChild.ParentApplicationRoleId, ApplicationRoleParentChild.ChildApplicationRoleId
, recursiveTable.TopLevelName
FROM ApplicationRoleParentChild
INNER JOIN recursiveTable ON ApplicationRoleParentChild.ParentApplicationRoleId = recursiveTable.ChildApplicationRoleId
)
或者您甚至可以构建 child
的完整路径 WITH recursiveTable(ParentApplicationRoleId, ChildApplicationRoleId, TopLevelName)
AS
(
SELECT ParentApplicationRoleId, ChildApplicationRoleId, cast(Name as varchar(1000))
FROM ApplicationRoleParentChild
UNION ALL
SELECT ApplicationRoleParentChild.ParentApplicationRoleId, ApplicationRoleParentChild.ChildApplicationRoleId
, left(recursiveTable.TopLevelName + '/' + name, 1000)
FROM ApplicationRoleParentChild
INNER JOIN recursiveTable ON ApplicationRoleParentChild.ParentApplicationRoleId = recursiveTable.ChildApplicationRoleId
)
然后像 where Parent.TopLevelName like '%Administrator%'
更新
如通知
Ivan Starostin 在他的评论中
如果您不想将每条记录都作为顶级来获得所有层次结构的组合。
您必须为 cte 中的第一个 select 添加 where
子句以定义顶级节点。
类似于 ParentApplicationRoleId is NULL
或 ParentApplicationRoleId = ''