我将尝试使用SQL2016中的FOR JSON PATH将XML列转换为Json,但是我遇到了一些问题。给定以下XML(请注意,某些Product元素可能包含Product列表):
我可以在SQL中运行以下语句(其中@xml是上面的XML):
它生成的Json格式大致如下:
你可以看到的问题是,生成的Json中所有元素最终都与所有产品相关,而不考虑它们的父关系。 我想我漏掉了一个WHERE子句,应该在其中检查它是否属于父节点,但我无法想出如何做到。我尝试添加节点Product[@id="3123"](请参见已注释的行),但我需要用实际的父ID替换“3123”,而我不知道如何操作。另一个选择是实际上保存父ID(请参见已注释的行ParentId),然后在结果中使用JSON_MODIFY删除不匹配的元素,但我也没有成功。 有人有任何想法,我该如何解决这个问题? 或者我还能做什么?--编辑这是我期望的Json:
您可以假设如果Level=1,那么不会有产品子层级,而如果Level=2,则将有一个产品子层级。
谢谢。
<Request>
<SelectedProducts>
<Product id="D04C01S01" level="1" />
<Product id="158796" level="1" />
<Product id="7464" level="2">
<Product id="115561" level="3" />
</Product>
<Product id="907" level="2">
<Product id="12166" level="3" />
<Product id="33093" level="3" />
<Product id="33094" level="3" />
<Product id="28409" level="3" />
</Product>
<Product id="3123" level="2">
<Product id="38538" level="3" />
<Product id="37221" level="3" />
</Product>
</SelectedProducts>
</Request>
我可以在SQL中运行以下语句(其中@xml是上面的XML):
SELECT
d.value('./@id', 'varchar(50)') AS 'Id'
,d.value('./@level', 'int') AS 'Level'
,(SELECT
--f.value('../@id', 'varchar(50)') AS 'ParentId'
f.value('./@id', 'varchar(50)') AS 'Id'
,f.value('./@level', 'int') AS 'Level'
--FROM @xml.nodes('/Request/SelectedProducts/Product[@id="3123"]/Product') AS e(f)
FROM @xml.nodes('/Request/SelectedProducts/Product/Product') AS e(f)
FOR JSON PATH) 'Product'
FROM @xml.nodes('/Request/SelectedProducts/Product') AS c(d)
FOR JSON PATH
它生成的Json格式大致如下:
[{"Id":"D04C01S01",
"Level":2,
"Product":[{"Id":"115561", "Level":3 }, {"Id":"12166","Level":3 }, { Id":"33093", "Level":3 }, {"Id":"33094","Level":3 }, {"Id":"28409","Level":3},
{"Id":"38538","Level":3},{"Id":"37221","Level":3 }]},
{"Id":"158796",
"Level":3,
"Product":[{"Id":"115561", "Level":3 }, {"Id":"12166","Level":3 }, { Id":"33093", "Level":3 }, {"Id":"33094","Level":3 }, {"Id":"28409","Level":3},
{"Id":"38538","Level":3},{"Id":"37221","Level":3 }]...
你可以看到的问题是,生成的Json中所有元素最终都与所有产品相关,而不考虑它们的父关系。 我想我漏掉了一个WHERE子句,应该在其中检查它是否属于父节点,但我无法想出如何做到。我尝试添加节点Product[@id="3123"](请参见已注释的行),但我需要用实际的父ID替换“3123”,而我不知道如何操作。另一个选择是实际上保存父ID(请参见已注释的行ParentId),然后在结果中使用JSON_MODIFY删除不匹配的元素,但我也没有成功。 有人有任何想法,我该如何解决这个问题? 或者我还能做什么?--编辑这是我期望的Json:
[{"Request":
[{"Id":"D04C01S01","Level":1 },
{"Id":"158796","Level":1},
{"Id":"7464","Level":2,"Product":[{"Id":"115561","Level":3}]},
{"Id":"907","Level":2,"Product":[{"Id":"12166","Level":3},{"Id":"33093","Level":3},{"Id":"33094","Level":3},{"Id":"28409","Level":3}]},
{"Id":"3123","Level":2,"Product":[{"Id":"38538","Level":3},{"Id":"37221","Level":3}]}]}]
您可以假设如果Level=1,那么不会有产品子层级,而如果Level=2,则将有一个产品子层级。
谢谢。