我试图找出如何在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)
)
我想编写一个存储过程,该过程将获取一个对象id并吐出所有对象依赖项(类似这样,但也发现任何依赖项依赖项。
SELECT id, ObjectDependency.id FROM Object
JOIN ObjectDependency ON object_id = id
系统的设置方式是没有周期性的依赖性,但我对如何将所有结果循环到一个存储过程中感到很遗憾。
答案 0 :(得分:2)
如果您使用的是SQL Server 2005或更高版本,则可以使用递归CTE (公用表表达式)来执行此操作(有关详细信息,请参阅MSDN Books Online docs)。
基本上,它是一个“内联视图” - 仅存在于下一个语句的视图。 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
第二步一遍又一遍地重复,直到不再检索到其他行 - 然后返回结果集。