gpt4 book ai didi

sql - 使用 FOR XML PATH 时如何删除嵌套查询中的冗余 namespace

转载 作者:数据小太阳 更新时间:2023-10-29 01:39:41 29 4
gpt4 key购买 nike

UPDATE: I've discovered there is a Microsoft Connect item raised for this issue here

当使用 FOR XML PATHWITH XMLNAMESPACES 声明默认命名空间时,对于使用 FOR XML 的嵌套查询,我将在任何顶级节点中复制命名空间声明,我在网上偶然发现了一些解决方案,但我并不完全相信......

这是一个完整的例子

/*
drop table t1
drop table t2
*/
create table t1 ( c1 int, c2 varchar(50))
create table t2 ( c1 int, c2 int, c3 varchar(50))
insert t1 values
(1, 'Mouse'),
(2, 'Chicken'),
(3, 'Snake');
insert t2 values
(1, 1, 'Front Right'),
(2, 1, 'Front Left'),
(3, 1, 'Back Right'),
(4, 1, 'Back Left'),
(5, 2, 'Right'),
(6, 2, 'Left')



;with XmlNamespaces( default 'uri:animal')
select
a.c2 as "@species"
, (select l.c3 as "text()"
from t2 l where l.c2 = a.c1
for xml path('leg'), type) as "legs"
from t1 a
for xml path('animal'), root('zoo')

什么是最好的解决方案?

最佳答案

经过数小时的绝望和数百次试验和错误后,我想出了以下解决方案。

我有同样的问题,当我想要 只有一个 xmlns 属性时,在 root 节点上只有 .但是我也遇到了一个非常困难的查询,其中包含很多子查询,而且单独使用 FOR XML EXPLICIT 方法太麻烦了。所以,是的,我希望在子查询中方便地使用 FOR XML PATH 并设置我自己的 xmlns

我借用了8kb答案的代码,因为它太好了。为了更好地理解,我对其进行了一些调整。这是代码:

DECLARE @Order TABLE (OrderID INT, OrderDate DATETIME)    
DECLARE @OrderDetail TABLE (OrderID INT, ItemID VARCHAR(1), Name VARCHAR(50), Qty INT)
INSERT @Order VALUES (1, '2010-01-01'), (2, '2010-01-02')
INSERT @OrderDetail VALUES (1, 'A', 'Drink', 5),
(1, 'B', 'Cup', 2),
(2, 'A', 'Drink', 2),
(2, 'C', 'Straw', 1),
(2, 'D', 'Napkin', 1)

-- Your ordinary FOR XML PATH query
DECLARE @xml XML = (SELECT OrderID AS "@OrderID",
(SELECT ItemID AS "@ItemID",
Name AS "data()"
FROM @OrderDetail
WHERE OrderID = o.OrderID
FOR XML PATH ('Item'), TYPE)
FROM @Order o
FOR XML PATH ('Order'), ROOT('dummyTag'), TYPE)

-- Magic happens here!
SELECT 1 AS Tag
,NULL AS Parent
,@xml AS [xml!1!!xmltext]
,'http://test.com/order' AS [xml!1!xmlns]
FOR XML EXPLICIT

结果:

<xml xmlns="http://test.com/order">
<Order OrderID="1">
<Item ItemID="A">Drink</Item>
<Item ItemID="B">Cup</Item>
</Order>
<Order OrderID="2">
<Item ItemID="A">Drink</Item>
<Item ItemID="C">Straw</Item>
<Item ItemID="D">Napkin</Item>
</Order>
</xml>

如果您单独选择@xml,您会看到它包含根节点dummyTag。我们不需要它,所以我们使用 directive 删除它FOR XML EXPLICIT 查询中的 xmltext:

,@xml AS [xml!1!!xmltext]

虽然 MSDN 中的解释听起来更复杂,但实际上它告诉解析器选择 XML 根节点的内容

不确定查询的速度有多快,但目前我正在放松,像个绅士一样喝着苏格兰威士忌,同时安静地看着代码......

关于sql - 使用 FOR XML PATH 时如何删除嵌套查询中的冗余 namespace ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3242070/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com