Хранимая процедура с использованием рекурсивного запроса - PullRequest
0 голосов
/ 30 мая 2018

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

Ниже приведены сохраненная процедура / функция и команда запуска (от новой к хранимой процедуре).

CREATE FUNCTION dbo.Ancestors (@List VARCHAR(MAX))
RETURNS TABLE
AS
RETURN
WITH CTE AS
(
 SELECT DISTINCT Child AS RESULT FROM example WHERE Parent IN( SELECT Id = 
 Item FROM dbo.SplitInts(@List, ',')) or child IN (SELECT Id = Item FROM 
 dbo.SplitInts(@List, ','))
 UNION ALL
 SELECT DISTINCT Parent AS RESULT FROM example WHERE Parent IN( SELECT Id = 
 Item FROM dbo.SplitInts(@List, ',')) or child IN (SELECT Id = Item FROM 
 dbo.SplitInts(@List, ','))
 )
SELECT RESULT FROM CTE
UNION
SELECT RESULT FROM CTE
GO

CREATE PROCEDURE GetAncestors (@thingID VARCHAR(MAX))
AS
SELECT RESULT FROM dbo.Ancestors(@thingID)
GO

EXEC GetAncestors @thingID = '100'    

Результат - '100,101'

EXEC GetAncestors @thingID = '100,101'

Результат - '100,101,102'

EXEC GetAncestors @thingID = '100,101,102'

Результат - '100,101,102'

Что я на самом деле ищу, так это дать результат водин выстрел, пройдя 100 или 101 или 102

Результат должен быть - '100,101,102'

Ниже приведена таблица примеров:

|     Parent          |     Child        |
|---------------------|------------------|
|      100            |      101         |
|---------------------|------------------|
|      101            |      102         |
|---------------------|------------------|

1 Ответ

0 голосов
/ 30 мая 2018

Похоже, вам нужен простой рекурсивный запрос, который пересекает дерево вниз, начиная с заданного узла.CTE возвращает список пар (Parent, Child), поэтому я объединил их вместе, чтобы получить список отдельных узлов (и по пути удалить дубликаты).

Обратите внимание, что запрос рекурсивный.CTE (общее табличное выражение) ссылается на себя.

Образцы данных

Я добавил еще несколько строк, чтобы реально увидеть, что происходит.

DECLARE @T TABLE (Parent int, Child int);

INSERT INTO @T VALUES
(100, 101),
(101, 102),
(102, 103),
(103, 104),
(101, 108),
(108, 109),
(208, 209),
(209, 210);

Запрос

WITH
CTE
AS
(
    SELECT
        Parent, Child
    FROM @T
    WHERE Parent = 100

    UNION ALL

    SELECT
        T.Parent, T.Child
    FROM
        CTE
        INNER JOIN @T AS T ON T.Parent = CTE.Child
)
SELECT
    Parent AS Result
FROM CTE

UNION

SELECT
    Child AS Result
FROM CTE
;

Результат

Result
100
101
102
103
104
108
109

Вы можете поместить запрос в хранимую процедуру следующим образом:

CREATE PROCEDURE GetAncestors(@thingID int)
AS
BEGIN
    SET NOCOUNT ON;

    WITH
    CTE
    AS
    (
        SELECT
            Example.Parent, Example.Child
        FROM Example
        WHERE Parent = @thingID

        UNION ALL

        SELECT
            Example.Parent, Example.Child
        FROM
            CTE
            INNER JOIN Example ON Example.Parent = CTE.Child
    )
    SELECT
        Parent AS Result
    FROM CTE

    UNION

    SELECT
        Child AS Result
    FROM CTE
    ;

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