【发布时间】:2020-03-02 09:42:10
【问题描述】:
使用the instructions from the 1st answer here,我正在尝试在 SQL Server 2012 表中分解一些 XML,如下所示:
表A
+------+--------+
| ID | ColXML |
+------+--------+
| 0001 | <xml1> |
| 0002 | <xml2> |
| ... | ... |
+------+--------+
xml1 看起来像这样:
<Attributes>
<Attribute name="address1">301 Main St</Attribute>
<Attribute name="city">Austin</Attribute>
</Attributes>
xml2 看起来像这样:
<Attributes>
<Attribute name="address1">501 State St</Attribute>
<Attribute name="address2">Suite 301</Attribute>
<Attribute name="state">Texas</Attribute>
</Attributes>
在任何给定的行中都有不同数量的属性。
我正在尝试将其展平为如下所示的关系表:
+------+--------------+-----------+--------+-------+
| ID | address1 | address2 | city | state |
+------+--------------+-----------+--------+-------+
| 0001 | 301 Main St | NULL | Austin | NULL |
| 0002 | 501 State St | Suite 301 | NULL | Texas |
+------+--------------+-----------+--------+-------+
这是我尝试过的代码,它在表#T 中返回 0 行:
select dense_rank() over(order by ID, I.N) as ID,
F.N.value('(*:Name/text())[1]', 'varchar(max)') as Name,
F.N.value('(*:Values/text())[1]', 'varchar(max)') as Value
into #T
from TableA as T
cross apply T.Attributes.nodes('/ColXML') as I(N)
cross apply I.N.nodes('ColXML') as F(N);
declare @SQL nvarchar(max)
declare @Col nvarchar(max);
select @Col =
(
select distinct ','+quotename(Name)
from #T
for xml path(''), type
).value('substring(text()[1], 2)', 'nvarchar(max)');
set @SQL = 'select '+@Col+'
from #T
pivot (max(Value) for Name in ('+@Col+')) as P';
exec (@SQL);
任何帮助将不胜感激。
【问题讨论】:
-
#T 是临时表吗?
-
根据您的代码,您正在寻找示例 xml 中不存在的节点 ColXML
-
感谢关于示例数据、自己的代码和预期输出的好问题(我这边 +1)。你可能会refer to this very related question。我建议将您的值读入 EAV 暂存表并从那里开始。否则,您将不得不切碎您的 XLM 两次,一次是创建动态语句,另一次是读取它。这会很慢...
-
感谢您提供链接并推荐 EAV 暂存表,这绝对有帮助!
标签: sql sql-server xml xquery