February 23, 2015 at 3:15 am
Morning all,
i am trying to output the hierarchical data of a tree to xml format.
i can query the data from the tables into a friendly format like this:
create table dummy
(
id int,
childname nvarchar(max),
parentid int,
parentname nvarchar(max)
)
go
insert into dummy (id, childname, parentid, parentname)
select 2, 'Dirname A', 1, 'C:\' union
select 3, 'Dirname B', 1, 'C:\' union
select 4, 'File 1' , 2, 'Dirname A' union
select 5, 'File 2' , 2, 'Dirname A' union
select 6, 'Dirname C', 2, 'Dirname A' union
select 7, 'File 1' , 6, 'Dirname C'
--C:\
--Dirname A
--File 1
--File 2
--Dirname C
--File 1
--Dirname B
and i always know the root ID from the first record on "table" dummy (generated with a common table expression), in this case it's ID 1
but from here, how to process this for any level of depth ?
February 23, 2015 at 8:39 am
You'll need a function for this
CREATE FUNCTION dbo.GetHier(@parentid INT)
RETURNS XML
WITH RETURNS NULL ON NULL INPUT
BEGIN RETURN
(SELECT childname AS "@name",
dbo.GetHier(id)
FROM dummy
WHERE parentid = @parentid
FOR XML PATH('node'),TYPE)
END
GO
SELECT parentname AS "@name",
dbo.GetHier(parentid)
FROM dummy
WHERE parentid = 1
GROUP BY parentid,parentname
FOR XML PATH('node'),TYPE;
____________________________________________________
Deja View - The strange feeling that somewhere, sometime you've optimised this query before
How to get the best help on a forum
http://www.sqlservercentral.com/articles/Best+Practices/61537February 23, 2015 at 8:45 am
Hello Mark,
i was browsing the forum for similar questions and indeed found an old thread where you adviced the same.
do you think i can use this solution with a memory table ?
February 23, 2015 at 8:55 am
This may be possible with table valued parameters, can you post a bit more information on what you have.
____________________________________________________
Deja View - The strange feeling that somewhere, sometime you've optimised this query before
How to get the best help on a forum
http://www.sqlservercentral.com/articles/Best+Practices/61537February 23, 2015 at 9:05 am
i generate the "data" i need like this
;WITH data AS
(
SELECT descendants.id as id, descendants.name AS childname, ancestors.id as parentid, ancestors.name as parentname FROM TreePaths paths
INNER JOIN Treelabels ancestors ON ancestors.id = paths.ancestor
INNER JOIN Treelabels descendants ON descendants.id = paths.descendant
WHERE paths.length = 1 and paths.active=1
),
recursion AS
(
SELECT c1.id, c1.childname, c1.parentid, c1.parentname, 1 as level
FROM data c1
WHERE c1.parentid NOT IN (SELECT id FROM data c2)
UNION ALL
SELECT t.id, t.childname, t.parentid, t.parentname, h.Level + 1 AS 'Level'
FROM recursion h
INNER JOIN data t ON t.parentid = h.id
)
select * from recursion
February 23, 2015 at 9:28 am
This should work for you
CREATE TYPE dbo.HierTVP AS TABLE
(
id int,
childname nvarchar(max),
parentid int,
parentname nvarchar(max)
)
GO
CREATE FUNCTION dbo.GetHier(@parentid INT, @HierTVP dbo.HierTVP READONLY)
RETURNS XML
WITH RETURNS NULL ON NULL INPUT
BEGIN RETURN
(SELECT childname AS "@name",
dbo.GetHier(id, @HierTVP)
FROM @HierTVP
WHERE parentid = @parentid
FOR XML PATH('node'),TYPE)
END
GO
DECLARE @HierTVP dbo.HierTVP;
WITH data AS
(
SELECT descendants.id as id, descendants.name AS childname, ancestors.id as parentid, ancestors.name as parentname FROM TreePaths paths
INNER JOIN Treelabels ancestors ON ancestors.id = paths.ancestor
INNER JOIN Treelabels descendants ON descendants.id = paths.descendant
WHERE paths.length = 1 and paths.active=1
),
recursion AS
(
SELECT c1.id, c1.childname, c1.parentid, c1.parentname, 1 as level
FROM data c1
WHERE c1.parentid NOT IN (SELECT id FROM data c2)
UNION ALL
SELECT t.id, t.childname, t.parentid, t.parentname, h.Level + 1 AS 'Level'
FROM recursion h
INNER JOIN data t ON t.parentid = h.id
)
INSERT INTO @HierTVP(id,childname,parentid,parentname)
SELECT id,childname,parentid,parentname
FROM recursion;
SELECT parentname AS "@name",
dbo.GetHier(parentid,@HierTVP)
FROM @HierTVP
WHERE parentid = 1
GROUP BY parentid,parentname
FOR XML PATH('node'),TYPE;
____________________________________________________
Deja View - The strange feeling that somewhere, sometime you've optimised this query before
How to get the best help on a forum
http://www.sqlservercentral.com/articles/Best+Practices/61537February 23, 2015 at 9:32 am
Thank you Mark, perfect !!
Viewing 7 posts - 1 through 6 (of 6 total)
You must be logged in to reply to this topic. Login to reply