Рекурсивные запросы в SQL Server - PullRequest
0 голосов
/ 04 декабря 2011

Я пытаюсь понять, как выполнить рекурсивный запрос в SQL.У меня есть две таблицы:

TABLE Object(
id INT NOT NULL PRIMARY KEY
)

TABLE ObjectDependency(
object_id INT,
dependency_id INT,
FOREIGN KEY(object_id)     REFERENCES Object(id)
FOREIGN KEY(dependency_id) REFERENCES Object(id)
)

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

SELECT id, ObjectDependency.id FROM Object
JOIN ObjectDependency ON object_id = id 

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

1 Ответ

2 голосов
/ 04 декабря 2011

Если вы используете SQL Server 2005 или новее, вы можете использовать для этого рекурсивный CTE (общее табличное выражение) (см. Электронная документация MSDN Books для получения более подробной информации)..

По сути, это «встроенное представление» - представление, которое существует только для следующего оператора.Одна версия CTE разработана специально для обработки рекурсивных сценариев.

Это выглядит примерно так:

CREATE PROCEDURE dbo.RecurseObjects @ObjectID INT
AS BEGIN
  WITH ObjectCTE AS 
  (
      -- set the anchor - select the object defined
      SELECT o.id AS 'ID', CAST(NULL AS INT) AS 'ParentID', 1 AS 'Level'
      FROM dbo.Object o
      WHERE o.id = @ObjectID

      -- add recursion
      UNION ALL

      SELECT o2.id AS 'ID', cte.id AS 'ParentID', cte.Level + 1 AS 'Level'
      FROM dbo.Object o2
      INNER JOIN dbo.ObjectDependency od ON od.dependency_id = o2.id
      INNER JOIN ObjectCTE cte ON cte.id = od.object_id
  )
  SELECT *
  FROM ObjectCTE
END

Итак, этот рекурсивный CTE запускается поэтапно:

  • первый «запуск» устанавливает привязку, то есть выполняется первый SELECT, а результаты сохраняются во временном наборе результатов
  • , затем обрабатывается рекурсия: второй выборвыполняется, в основном выбирая все строки, которые зависят от строк, выбранных в первом запуске - все те, которые связаны следующим образом:

    object.id --> objectdepedency.dependecy_id 
                  objectdepedency.object_id --> "parent" object.id
    

Этот второй шаг повторяетсяснова и снова, пока больше не будет извлечено дополнительных строк - тогда возвращается набор результатов.

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