N-многоуровневая трасса для родителей и детей - от петли к вершине - PullRequest
1 голос
/ 10 ноября 2011

Я пытаюсь построить цепочку, основанную на отношениях родитель / потомок в таблице базы данных SQL. Я делал это в прошлом, но сейчас мне нужно пройтись по иерархии снизу вверх (назад).

Вот как выглядит мой DataTable:

DocID | ParentDocID | Имя
7 | 0 | Изображения (Root)
24 | 7 | JPG (Уровень 2)
34 | 24 | Размер (Уровень 3)

Так что это N-уровневая архитектура. Я всегда знаю, на каком уровне я нахожусь через строковую переменную запроса. Мне нужно зациклить снизу вверх, чтобы пользователь мог отметить, на каком уровне структуры уровня они находятся. У меня проблемы с выяснением этого. Я не могу использовать сессию или viewstate.

Желаемые результаты:

Пользователь переходит по этой ссылке: Default.aspx? DocId = 34 - тогда они видят след крошки как таковой:
Home > Изображения > JPG > Размер

Default.aspx? DocId = 24 - Тогда они видят след крошки как таковой:
Home > Изображения > JPG

Элемент «Дом», который я жестко запрограммировал. Мне также нужно, чтобы каждый элемент в трейле связывался, за исключением уровня, на котором вы находитесь.

Я бы предпочел, чтобы это было сделано в коде C #. Я также открыт для параметров хранимой процедуры уровня SQL.

Любая помощь будет принята с благодарностью. Заранее спасибо!

Вот некоторый SQL, который я пытаюсь, но не получаю нужные мне результаты. Надеюсь, это поможет:

WITH Hierachy([DocID], [ParentDocID], [Name], [Level]
AS
(
SELECT [DocID], [ParentDocID], [Name], 0 AS [Level]
FROM [Documents] d
WHERE (d.[ParentDocID] = 7) AND ([Folder] = 1) AND ([Status] = 'A') AND ([AppGroupID] = 4)
UNION ALL
SELECT d.[DocID], d.[ParentDocID], d.[Name], dh.[Level] + 1
FROM [Documents] d
INNER JOIN Hierachy dh
--ON d.ParentDocID = dh.DocID
ON dh.[ParentDocID] = d.[DocID] -- bottom up apporach
WHERE ([Folder] = 1) AND ([Status] = 'A') AND ([AppGroupID] = 4)
)
SELECT [DocID], [ParentDocID], [Name]
FROM Hierachy
--WHERE [Level] > 0

Я понял! Вот SQL, который работает:

WITH Hierachy([DocID], [ParentDocID], [Name], [Level])
AS
(
SELECT [DocID], [ParentDocID], [Name], 0 AS [Level]
FROM [Documents] d
WHERE (d.[DocID] = @ParentDocID) AND ([Folder] = 1) 
AND ([Status] = 'A') AND ([AppGroupID] = @AppGroupID)
UNION ALL
SELECT d.[DocID], d.[ParentDocID], d.[Name], dh.[Level] + 1
FROM [Documents] d
INNER JOIN Hierachy dh
ON dh.[ParentDocID] = d.[DocID]
WHERE ([Folder] = 1) 
AND ([Status] = 'A') AND ([AppGroupID] = @AppGroupID)
)
SELECT [DocID], [ParentDocID], [Name]
FROM Hierachy
ORDER BY [Level] DESC
)

Ответы [ 3 ]

0 голосов
/ 10 ноября 2011

Это описывает решение аналогичной проблемы, то есть хождение по дереву.Любой встроенный sql, такой как этот, лучше всего выполнять в хранимой процедуре.Решение этой проблемы в SQL, вероятно, является наилучшим подходом, поскольку у вас уже есть все данные.

0 голосов
/ 27 августа 2014
0 голосов
/ 10 ноября 2011

Конечно, вы можете. Вы можете использовать CURSOR или WHILE LOOP или XML. У меня есть пример, как ты. Вот WHILE LOOP с временной таблицей, она выбирает родителей узла с предоставленным идентификатором:

DECLARE @ID INT = 4
DECLARE @Parent_ID INT
DECLARE @Tree TABLE
(
    ID int,
    Value NVARCHAR(10),
    Parent_ID int
)

SELECT @Parent_ID = Parent_ID FROM Tree 
WHERE ID = @ID

WHILE @Parent_ID IS NOT NULL
BEGIN
    INSERT INTO @Tree
    SELECT * FROM Tree
    WHERE ID = @Parent_ID

    SELECT @Parent_ID = Parent_ID FROM Tree
    WHERE ID = @Parent_ID
END

SELECT * FROM @Tree
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...