2017-08-08 16 views
0

HierarchyIdを使用してソートされた商品のリストがありますが、項目の一部では、階層のフルパスが間違った結果を生成しています。ほんの数のために...イリノイ、以下の証明:SQL HierarchyId時には間違ったパスが生成される

SELECT 
    ProductId 
    ,Name 
    ,FullName 
    ,Hierarchy 
    ,Hierarchy.ToString() as hierarchyString 
    ,editor.ufn_Product_GetFullName(ProductId) as ufnGetFullName 
    ,Hierarchy.GetLevel() as [level] 
FROM Editor.Product 
WHERE ProductId = 378 
    OR Hierarchy.ToString() like '/16/1/1/%' 
    OR Hierarchy.ToString() = '/16/1/' 
    OR Hierarchy.ToString() = '/16/' 
    OR Hierarchy.ToString() = '/' 
ORDER BY Hierarchy.ToString() 

をそのクエリを使用して、私は結果を得る:

enter image description here は、プロシージャから返されたパスのほとんどは

を生産、罰金です

'外観>レンダリング>色>白'

しかし、それらのうち4つは最後の2つの用語のスワップPEDのような

「エクステリア>レンダリング>ホワイト>色」の用語は交換され、なぜ一部だけにしている理由

私は私の人生のために、把握することはできません。階層構造は正しいように見え、レベルはすべて子項目で正しいです。私はあなたの助けが必要です...

以下は、製品階層からパスを生成するために使用される関数ですが、どのように問題になるかはわかりません。

ALTER FUNCTION [Editor].[ufn_Product_GetFullName] (@ID INT) 
RETURNS VARCHAR(8000) 
AS BEGIN 
    -- Create and insert names into temp table 
    DECLARE @NamesTable TABLE (Name varchar(8000)); 

    INSERT @NamesTable (Name) 
     SELECT t1.Name 
     FROM ( SELECT ProductId, Hierarchy, Name 
       FROM Product WITH(NOLOCK) 
       WHERE (ProductId = @ID)) AS t2 
      CROSS JOIN Product AS t1 

     WHERE (t1.Hierarchy = t2.Hierarchy) 
     OR (t1.Hierarchy <> '/') 
     AND (t2.Hierarchy.IsDescendantOf(t1.Hierarchy) = 1) 

     ORDER BY t1.Hierarchy; 

    -- Define name string 
    DECLARE @Name VARCHAR(8000); 

    -- Coalesce names from temp table into one long string 
    SELECT @Name = COALESCE(@Name + ' > ', '') + Name 
    FROM @NamesTable 

    -- Return full string 
    RETURN @Name 
END 
+0

本当にMySQLコードですか? – jarlh

答えて

1

ORDER BY句がないと、行の順序がわからないことがあります。列Level@NamesTableをテーブルに追加します。文字列を連結しているSELECTORDER BY句を追加します。これは助けになるはずです。

ALTER FUNCTION [Editor].[ufn_Product_GetFullName] (@ID INT) 
RETURNS VARCHAR(8000) 
AS BEGIN 
    -- Create and insert names into temp table 
    DECLARE @NamesTable TABLE (Name varchar(8000), Level int); 

    INSERT @NamesTable (Name, Level) 
     SELECT t1.Name, t1.Hierarchy.getLevel() 
     FROM ( SELECT ProductId, Hierarchy, Name 
       FROM Product WITH(NOLOCK) 
       WHERE (ProductId = @ID)) AS t2 
      CROSS JOIN Product AS t1 

     WHERE (t1.Hierarchy = t2.Hierarchy) 
     OR (t1.Hierarchy <> '/') 
     AND (t2.Hierarchy.IsDescendantOf(t1.Hierarchy) = 1) 

     ORDER BY t1.Hierarchy; 

    -- Define name string 
    DECLARE @Name VARCHAR(8000); 

    -- Coalesce names from temp table into one long string 
    SELECT @Name = COALESCE(@Name + ' > ', '') + Name 
    FROM @NamesTable 
    ORDER BY Level 

    -- Return full string 
    RETURN @Name 
END 
+1

これを動作させるには、INSERT @NamesTable(Name)行にLevelを追加し、t1.Hierarchy.getLevel()にt1.levelを変更する必要がありましたが、それ以外の場合は完全に感謝しました:) – Xynos

+0

申し訳ありません!私はそれを完全に忘れてしまった。私は私の答えを更新します。 – Rokuto

関連する問題