0

我正在一个网站上工作,该网站的页面与父子关系排列在一个表中。页面深度可以达到任何级别,我想根据数据库为网站生成 BreadCrumb。示例数据和数据字段如下图所示。

基本表结构类似于 TableName Web_Pages

表列 (PageID int、PageName Varchar、PageInternalLinkURL Varchar、PageInheritance int)

表中样本数据示例 表数据示例

页面上的面包屑示例 页面上的面包屑示例

我希望网站导航的面包屑看起来类似于下面的示例图像中显示的内容。

我尝试了几个星期,但无法做到正确。

我想在没有站点地图的情况下使用它,而是想以语法方式创建它并将PageName字段与正确的页面 URL 链接。

我想这样做,以便在将页面添加到 CMS 时动态创建可以与任何页面深度一起使用的面包屑。

我使用了无法正常工作的 CTE 查询。如果有人解决此问题或可以指出与我的类似的完整工作示例,我将不胜感激。

测试 CTE 不起作用

SELECT * FROM pg_Pages;
WITH RecursiveTable (PageId, PageInheritance, Level)
AS
(
   --Anchor
    SELECT      tt.PageId,  tt.PageInheritance,  0 AS Level
    FROM pg_Pages AS tt
    WHERE PageInheritance = 0
    UNION ALL
    --Recursive member definition
    SELECT  tt.PageId, tt.PageInheritance, LEVEL + 1
    FROM pg_Pages AS PageId
        INNER JOIN RecursiveTable rt ON
        tt.PageInheritance = rt.PageId
)
SELECT * 
FROM RecursiveTable
4

2 回答 2

2

看起来您的 CTE 是错误的 - 您快到了,但递归成员定义位看起来错误。

尝试:

SELECT * FROM pg_Pages;
WITH RecursiveTable (PageId, PageInheritance, Level)
AS
(
   --Anchor
    SELECT      tt.PageId,  tt.PageInheritance,  0 AS Level
    FROM pg_Pages AS tt
    WHERE PageInheritance = 0
    UNION ALL
    --Recursive member definition
    SELECT  tt.PageId, tt.PageInheritance, Level + 1
    FROM pg_Pages AS tt
        INNER JOIN RecursiveTable rt ON
        tt.PageInheritance = rt.PageId
)
SELECT * 
FROM RecursiveTable
--SELECT * FROM RecursiveTable WHERE Level = 0

在您最初的尝试中,您的 pg_Pages 别名必须是 tt (并且您还需要在 PageInheritance 前面加上 tt 前缀)。

否则,它看起来很好。

编辑

对于您的其他问题,您只需添加其他列:

SELECT * FROM pg_Pages;
WITH RecursiveTable (PageId, PageName, PageInternalLink, PageInternalLinkUrl, PageInheritance, Level)
AS
(
   --Anchor
    SELECT      tt.PageId,  tt.PageName, tt.PageInternalLink, tt.PageInternalLinkUrl, tt.PageInheritance,  0 AS Level
    FROM pg_Pages AS tt
    WHERE PageInheritance = 0
    UNION ALL
    --Recursive member definition
    SELECT  tt.PageId,  tt.PageName, tt.PageInternalLink, tt.PageInternalLinkUrl, tt.PageInheritance, Level + 1
    FROM pg_Pages AS tt
        INNER JOIN RecursiveTable rt ON
        tt.PageInheritance = rt.PageId
)
SELECT * 
FROM RecursiveTable
--SELECT * FROM RecursiveTable WHERE Level = 0

进一步编辑:

好的,做你想做的,你可以把查询转过来;如果您知道页面 ID:

DECLARE @PageId int
SET @PageId = 39;
WITH RecursiveTable (PageId, PageName, PageInternalLink, PageInternalLinkUrl, PageInheritance, Level)
AS(
   --Anchor
    SELECT      tt.PageId,  tt.PageName, tt.PageInternalLink, tt.PageInternalLinkUrl, tt.PageInheritance,  0 AS Level
    FROM TestPage AS tt
    WHERE PageId = @PageId
    UNION ALL
   --Recursion
    SELECT tt.PageId,  tt.PageName, tt.PageInternalLink, tt.PageInternalLinkUrl, tt.PageInheritance, Level + 1
    FROM TestPage AS tt
    INNER JOIN RecursiveTable rt ON rt.PageInheritance = tt.PageId
)
SELECT * FROM RecursiveTable ORDER BY Level DESC

我们在这里所做的是从您所在的页面开始,然后通过表格向后工作以寻找所有父母。在这种情况下,级别最高的记录是最终父项,因此我们按降序逐级排序以反映这一点。

于 2012-04-18T08:22:54.907 回答
0

假设您要检索 pageId 39 的面包屑,您可能需要尝试以下操作:

declare @pageId int

set @pageId=39;
WITH RecursiveTable (PageId,PageName, PageInheritance,PageInternalLinkURL, Level)
AS
(
   --Anchor
    SELECT      tt.PageId,tt.PageName,  tt.PageInheritance,tt.PageInternalLinkURL,  0 AS Level
    FROM pg_pages AS tt
    WHERE PageID = @pageId
    UNION ALL
    --Recursive member definition
    SELECT  tt.PageId,tt.PageName,  tt.PageInheritance,tt.PageInternalLinkURL, Level + 1
    FROM pg_pages AS tt
        INNER JOIN RecursiveTable rt ON
        rt.PageInheritance = tt.PageId
)
SELECT * 
FROM RecursiveTable
于 2012-04-18T09:40:09.613 回答