5

正常に動作するId、parentId、absoluteUrlsのリストを返すための以下のストアドプロシージャがあります。

ALTER PROCEDURE [dbo].[SearchDataManager.HierarchyById] 
    @currentId AS int   
AS
BEGIN
 DECLARE @id INT 
 DECLARE @parentId INT
 DECLARE @absoluteUrl NVARCHAR(1000)

 DECLARE @Hierarchy TABLE (Id int, ParentId int, AbsoluteUrl nvarchar(1000))

 WHILE @currentId != 0
 BEGIN

     SELECT @id = Id, @parentId = ParentId, @absoluteUrl = AbsoluteUrl
     FROM dbo.[SearchDataManager.NiceUrls]
     WHERE id = @currentId

     INSERT INTO @Hierarchy  VALUES (@id, @parentId, @absoluteUrl)

    SET @currentId = @parentId
 END

    SELECT * FROM @Hierarchy  
END

「NiceUrls」テーブルにはIdとParentIdがあります。parentIdは、同じテーブル内のレコードを参照します。

次のように戻ります。

 ----------------------------------
    Id  | ParentId | AbsoluteUrl
    ----------------------------------
    294 | 5        | url1
    5   | 2        | url2
    2   | 0        | url3

上記のコードは、WHILEループを使用してテーブル変数を定義すると正常に機能しますが、テーブルから階層データを取得するためのより良い方法があるのではないかと思います。

上記のコードの問題は保守性です。NiceUrlsテーブルの列をもう1つ返す必要がある場合は、新しい変数を定義したり、列をインラインテーブルに追加したりする必要があります。

spを書き直すより良い方法はありますか?

ありがとう、

何ですか

4

2 に答える 2

20
with Hierarchy (Id, ParentId, AbsoluteUrl, Level)
 AS
 (
    -- anchor member
     SELECT Id,
        ParentId,
        AbsoluteUrl,
        0 AS Level   
     FROM dbo.[NiceUrls]
     WHERE id = @currentId
     UNION ALL
     -- recursive members
     SELECT su.Id,
        su.ParentId,
        su.AbsoluteUrl,
        Level + 1 AS Level   
     FROM dbo.[NiceUrls] AS su
     INNER JOIN Hierarchy ON Hierarchy.ParentId = su.Id  
 )
 SELECT * FROM Hierarchy
于 2012-06-28T14:07:39.347 に答える
2

元のIDに関連するソーステーブルのすべてのレコードが必要なようです。

1)すべてのIDを提供するCTEを作成します(トリプルに記載されているリンクを参照)

2)このCTEを元のテーブルに結合します

于 2012-06-27T16:31:06.547 に答える