语句已终止。在语句完成之前,最大递归次数100已经耗尽。

3
我正在编写一个存储过程,用于检索菜单控件的xml结构。这段代码看起来是有效的(至少我认为是有效的),但在查询测试器上运行不良。如何更正它?以下是代码:
;WITH Hierarchy AS
(
    SELECT
        MenUid,MenuName,ApplicationId,ParentMenuId, 1 AS 'Level'
    FROM
        dbo.Menu
    WHERE
        ParentMenuId = '-1'

    UNION ALL

    SELECT
        M.MenUid,M.MenuName,M.ApplicationId,M.ParentMenuId, Level + 1 AS 'Level'
    FROM
        dbo.Menu M
    INNER JOIN
        Hierarchy h ON M.ParentMenuId = h.MenuId
)
SELECT *
FROM Hierarchy
ORDER BY [Level],[MenuName]

ParentMenuId和MenuId相关联。我还有一些疑问如下:

  1. 使用CTE来处理菜单是否完全可行?您还成功使用过哪些其他类型?
  2. DataSetChildRelations 对于这个目的也不错(或者我错了)?

请给我更多关于如何在您的项目中实现菜单系统的想法。

输入

MenuId      MenuName      ApplicationId    ParentMenuId

 1          MenuName1           1              -1

 2          MenuName2           1               1

 3          MenuName3           1               -1

 4          MenuName4           1               2

输出

<Output>
    <Menu>
        <MenuId>1</MenuId>
        <MenuName>MenuName1</MenuName>
        <ApplicationId>1</ApplicationId>
        <ParentMenuId>-1</ParentMenuId>
        <SubMenu>
            <Menu>
                <MenuId>2</MenuId>
                <MenuName>MenuName2</MenuName>
                <ApplicationId>1</ApplicationId>
                <ParentMenuId>1</ParentMenuId>
                <SubMenu>
                    <MenuId>3</MenuId>
                    <MenuName>MenuName4</MenuName>
                    <ApplicationId>1</ApplicationId>
                    <ParentMenuId>3</ParentMenuId>
                </SubMenu>
            </Menu>
        </SubMenu>
    </Menu>
    <Menu>
        <MenuId>4</MenuId>
        <MenuName>MenuName3</MenuName>
        <ApplicationId>1</ApplicationId>
        <ParentMenuId>-1</ParentMenuId>
    </Menu>
</Output>

不要担心XML结构,使用FOR XML PATH很容易获取它,但我首先无法运行查询。


你能提供测试数据和期望的输出吗? - Kirill Polishchuk
@KirillPolishchuk 请查看输入和输出部分。 - Deeptechtons
移除 .NET 标签:在这个问题中看不到任何关于 .NET 的内容。 - Richard
@Richard :) 好的,我之前提出的两个问题是:DataSet 和 ChildRelations。 - Deeptechtons
除非有不同的客户端使错误消失,否则客户端就无关紧要。 - Richard
2个回答

5

我敢打赌

INNER JOIN
    Hierarchy h ON M.ParentMenuId = h.ParentMenuId

应该实际上是

INNER JOIN
    Hierarchy h ON M.ParentMenuId = h.MenuId

编辑

使用这个样例数据:

declare @Menu table (
    MenuId int,
    MenuName nvarchar(20),
    ApplicationId int,
    ParentMenuId int
)

insert @Menu values
(1, 'Name1', 1, -1),
(2, 'Name2', 1,  1),
(3, 'Name3', 1, -1),
(4, 'Name4', 1,  2)

经过上述修改后,我得到了您的查询结果。
MenUid      MenuName             ApplicationId ParentMenuId Level
----------- -------------------- ------------- ------------ -----------
1           Name1                1             -1           1
3           Name3                1             -1           1
2           Name2                1             1            2
4           Name4                1             2            3

看起来正确。为了帮助您,我们需要查看 所有 相关的代码。


现在查询已经可以运行,但是我没有得到期望的结果。请检查输入和输出部分。 - Deeptechtons
谢谢。我现在发现很难生成XML结构,因为不允许在联合中使用FOR XML PATH。 - Deeptechtons
这是我正在尝试做的事情:http://richarddingwall.name/2008/08/30/more-nested-xml-with-sql-server-n-level-tree-recursion/ - Deeptechtons
@Deeptechtons 正如博客文章中所解释的那样,在这种情况下,您必须使用用户定义的函数。 - AakashM

1

如果直接获取数据并在应用层进行构建工作,这样不是更容易吗?

编辑:

一般情况下,我不建议使用缓存方法。但是,如果菜单生成代码很耗费资源,并且假设菜单不会经常更改,那么这将成为缓存的好目标。


好的,这在数据库上是可能的,所以我为什么不应该尝试呢。我会尝试两种方法,对它们进行分析,最终做出决定。 - Deeptechtons
我怀疑应用程序代码将更高效地执行操作,并且分离应用层更容易。 - Jodrell
我会遵循这个问题。但是我不能将您的答案标记为答案,因为Aakash最初回答了我提出的问题。在我在数据库方面做正确的事情之前,我必须在应用程序层面上完成这项工作。谢谢 :) - Deeptechtons

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接