SQL ServerでXMLパスを使用して階層データのXML出力を取得するクエリ
-
27-09-2019 - |
質問
列nodeid、nodename、parentnodeidを備えたテーブルがあり、sqlクエリを使用して次のようにxmlの形でテーブルデータ全体を挿入したいと思います。 SQL ServerのXMLパスモードの場合、再帰を使用してこれを実現するために使用できると思いますが(SQL Server 2008を使用します)、方法はわかりません。前もって感謝します
<?xml version="1.0" encoding="utf-8" ?>
<Nodes>
<Node Id="1" Name="node1">
<Node Id="11" Name="node11">
<Node Id="111" Name="node111" />
<Node Id="112" Name="node112" />
</Node>
</Node>
<Node Id="2" Name="node2">
<Node Id="21" Name="node21">
<Node Id="211" Name="node211" />
<Node Id="212" Name="node212" />
</Node>
</Node>
</Nodes>
解決
ストアドプロシージャと再帰機能を使用して解決しました。以下に示すコード。 (実際、これがメニューXMLを生成することを望んでいたので、メニューにコードが表示されます。
CREATE PROCEDURE [dbo].[usp_GetMenu]
AS
BEGIN
SET NOCOUNT ON;
SELECT dbo.fnGetMenuItems(MenuId)
FROM dbo.Menu
WHERE ParentMenuId IS NULL
FOR XML PATH('MenuItems')
END
GO
CREATE FUNCTION [dbo].[fnGetMenuItems]
(
@MenuId int
)
RETURNS XML
WITH RETURNS NULL ON NULL INPUT
AS
BEGIN
RETURN
(
SELECT MenuId AS "@Id"
, [Name] AS "@Name"
, [URL] AS "@URL"
, [Key] AS "@Key"
, [dbo].[fnGetMenuItems](MenuId)
FROM dbo.Menu
WHERE ParentMenuId = @MenuId
FOR XML PATH('MenuItem'),TYPE
)
END
GO
他のヒント
このクエリはそれを行います - ただし、ネストを「手動で」定義する必要があるという点でそれほどきれいではなく、より多くのレベルの深さに自動的にスケーリングするわけではありません。
SELECT
n.ID AS '@Id',
n.NAME AS '@Name',
(SELECT
n2.ID AS '@Id',
n2.NAME AS '@Name',
(SELECT
n3.ID AS '@Id',
n3.NAME AS '@Name'
FROM
dbo.Nodes n3
WHERE
n3.ParentNode = n2.ID
FOR XML PATH('Node'), TYPE
)
FROM
dbo.Nodes n2
WHERE
n2.ParentNode = n.ID
FOR XML PATH('Node'), TYPE
)
FROM
dbo.Nodes n
WHERE
n.ParentNode IS NULL
FOR XML PATH('Node'), ROOT('Nodes')
出力は次のとおりです。
<Nodes>
<Node Id="1" Name="node1">
<Node Id="11" Name="node11">
<Node Id="111" Name="node111" />
<Node Id="112" Name="node112" />
</Node>
</Node>
<Node Id="2" Name="node2">
<Node Id="21" Name="node21">
<Node Id="211" Name="node211" />
<Node Id="212" Name="node212" />
</Node>
</Node>
</Nodes>
私はこれを再帰CTE(一般的なテーブル式)で行う方法があることを望んでいましたが、それはうまくいきませんでした:-(
所属していません StackOverflow