具体ID的层次结构

时间:2019-06-22 15:14:47

标签: sql-server tsql sql-server-2014

我有一个递归数据库表和所有表数据的分层视图

CREATE VIEW dbo.vw_hierarchicalView
AS
    WITH hView (Id,
                    IdParent,
                    Level)
    AS
    (
        SELECT tableParent.Id,
               tableParent.IdParent,
               1 AS Level
        FROM dbo.vw_ComplaintWithStatus tableParent
        WHERE tableParent.IdParent IS NULL
        UNION ALL SELECT tableChild.Id,
                         tableChild.IdParent,
                         hw.level + 1 AS  Level
                 FROM dbo.vw_ComplaintWithStatus tableChild
                      INNER JOIN hView hw ON  tableChild.IdParent = hw.Id
    )
    SELECT final.Id,
           final.IdParent,
           ISNULL(final.Level, 1) AS Level
    FROM hView final

当我查询所有数据时,所有树都是正确的。

SELECT * FROM dbo.vw_hierarchicalView hw ORDER BY hw.Level, hw.Id

但是,如果我只想为一个ID选择全树,查询只显示具有指定ID的第一行

SELECT * FROM dbo.vw_hierarchicalView hw WHERE hw.Id = 5 ORDER BY hw.Level, hw.Id

我想在我的应用程序中使用它来使用实体框架在树中查找所有子记录。

应用程序逻辑向我返回了一些记录,需要查找: 1)仅第一个直子记录 2)所有孩子的记录(用于在网页中显示树)

我从视图中选择要存储过程的类,并以Id作为此过程的参数,并替换条件WHERE tableParent.IdParent在WHERE tableParent.Id = @id上为NULL。此解决方案效果很好,但是...

我不想使用存储过程。

没有数据库功能或过程,有什么办法解决这个问题?

1 个答案:

答案 0 :(得分:1)

您可以使用表值函数:

CREATE FUNCTION my_func(@root_id INT)
RETURNS TABLE
AS
RETURN
WITH hView (Id,IdParent,Level) AS
    (
        SELECT tableParent.Id,
               tableParent.IdParent,
               1 AS Level
        FROM dbo.vw_ComplaintWithStatus tableParent
        WHERE (tableParent.IdParent IS NULL  AND @root_id IS NULL)
           OR Id = @root_id
        UNION ALL SELECT tableChild.Id,
                         tableChild.IdParent,
                         hw.level + 1 AS  Level
                 FROM dbo.vw_ComplaintWithStatus tableChild
                      INNER JOIN hView hw ON  tableChild.IdParent = hw.Id
    )
    SELECT final.Id,
           final.IdParent,
           ISNULL(final.Level, 1) AS Level
    FROM hView final;

致电:

SELECT * FROM dbo.my_func(NULL) hw ORDER BY hw.Level, hw.Id;
--
SELECT * FROM dbo.my_func(5) hw ORDER BY hw.Level, hw.Id;