我有一个产品列表,使用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()
使用该查询我获得结果:
然而,其中有四个产生了最后两个交换的术语,如'外观>渲染>颜色>白'
'外观>渲染>白色>色'
我不能为我的生活,弄清楚为什么条款被交换,为什么只有一些。层次结构看起来正确,并且子项的级别都是正确的。我需要你的帮助......
以下是用于从产品层次结构生成路径的函数,但我不了解它是如何成为问题的。
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 :(得分:1)
如果没有ORDER BY
子句,则无法确定行顺序。将列Level
添加到@NamesTable
表。将ORDER BY
子句添加到正在连接字符串的SELECT
。这应该有所帮助。
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