0

CTEを使用したSQL再帰のこの優れた例を見つけましたが、テーブルに適用できませんでした。

次のテーブル(ObjectStates)があります。

ID    Title    ParentID
1     Draft    null
2     Green    null
3     Red      null
4     Foo      1
5     Bar      4

クエリ時に「メイン」状態を返す関数を作成しようとしています。例:

GetMainState(5)
-- Shall return 1
GetMainState(4)
-- Shall return 1
GetMainState(2)
-- Shall return 2

私はこれまでに持っています:

CREATE FUNCTION [dbo].[GetMainObjectState] (@ObjectStateID INT)
RETURNS TABLE
AS
RETURN 
(
 WITH StateRecurcsion(ID, ParentID, Level) AS
       (
           SELECT ID, ParentID, 0
           FROM ObjectStates
           WHERE ID = @ObjectStateID
           UNION ALL
           SELECT uOS.ID, uOS.ParentID, sOS.Level+1
           FROM ObjectStates uOS, StateRecurcsion sOS
           WHERE uOS.ParentID= sOS.ID
       )
 SELECT os.ID, os.Title, sos.Level
 FROM ObjectStates os, StateRecurcsion sos
 WHERE os.ID = sos.ID
)
GO

上記のチュートリアルと同じように関数を作成しようとしましたが、どういうわけか正しい結果が得られません。

4

1 に答える 1

1

「ルート」値を含むCTEを作成し、関数内でクエリを実行できます。例:

;WITH CTEHierarchy
AS (
    SELECT 
    ID
        ,0 AS LEVEL
        ,ID AS root

    FROM ObjectStates
    WHERE  ParentID IS NULL

    UNION ALL

    SELECT 
    ObjectStates.ID
        ,LEVEL + 1 AS LEVEL
        ,[root]

    FROM ObjectStates
    INNER JOIN CTEHierarchy uh ON uh.id = ObjectStates.ParentID
    )    
    SELECT [root]
    FROM CTEHierarchy
    WHERE ID = @ObjectStateID 
于 2012-11-21T11:32:03.477 に答える