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 NULLParentApplicationRoleId = ''