2011-12-04 72 views
0

我想弄清楚如何執行本質上是SQL中的遞歸查詢。我有兩張桌子;在SQL Server中的遞歸式查詢

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

如果只有您有權訪問遞歸CTE ... ;-) – 2011-12-04 00:57:41

+0

爲此,針對不同數據庫產品(Oracle/Mysql/PostgreSQL/MS SQL/...)有不同的解決方案。你在使用哪一個? –

+0

我正在使用MS SQL。 – user308926

回答

2

如果您使用的是SQL Server 2005或更新的版本,那麼您可以使用遞歸CTE 01的(公用表表達式)來完成此操作(有關更多詳細信息,請參閱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被執行,結果存儲在臨時結果集中
  • 然後處理遞歸:運行第二個select,基本上從第一次運行中選擇的行中選擇所有依賴的行 - 全部th被鏈接這樣OSE:

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

該第二步驟反覆重複,直到沒有更多的額外行被檢索 - 然後被返回的結果集。