Иерархическая структура для конкретного идентификатора - PullRequest
1 голос
/ 22 июня 2019

У меня есть рекурсивная таблица базы данных и иерархическое представление всех данных таблицы

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

Но, если я хочу выбрать полное дерево только для одного идентификатора, запрос покажет мне только первую строку с указанным идентификатором

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

Я хочу использовать это в своем приложении, чтобы найти все дочерние записи в дереве, используя каркас сущностей.

Логика приложения возвращает мне некоторую запись и нужно найти: 1) только первые прямые записи о детях 2) все дочерние записи (для отображения дерева на веб-странице)

I класс для выбора из представления для сохранения процедуры с Id в качестве аргумента этой процедуры и замены условия WHERE tableParent.IdParent IS NULL на WHERE tableParent.Id = @id. Это решение хорошо работает, но ...

Я скорее не хочу использовать процедуры магазина.

Есть ли способ решить эту проблему без функций или процедур базы данных?

1 Ответ

1 голос
/ 22 июня 2019

Вы можете использовать табличную функцию:

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;
...