XML分解动态SQL

问题描述 投票:0回答:1

使用the instructions from the 1st answer here,我试图在看起来像这样的MS SQL 2012表中切碎一些XML:

TableA

+------+--------+
|  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);

任何帮助将不胜感激-谢谢您的宝贵时间!

sql xml xquery
1个回答
0
投票

这里是一个DDL和XQuery以将表中的XML切碎。

SQL

-- DDL and sample data population, start
DECLARE @tbl TABLE (ID VARCHAR(10) PRIMARY KEY, ColXML XML);
INSERT INTO @tbl (ID, ColXML)
VALUES
('0001', N'<Attributes>
    <Attribute name="address1">301 Main St</Attribute>
    <Attribute name="city">Austin</Attribute>
</Attributes>'),
('0002', N'<Attributes>
    <Attribute name="address1">501 State St</Attribute>
    <Attribute name="address2">Suite 301</Attribute>
    <Attribute name="state">Texas</Attribute>
</Attributes>');
-- DDL and sample data population, start

SELECT ID
    , col.value('(Attribute[@name="address1"])[1]','VARCHAR(30)') AS [address1]
    , col.value('(Attribute[@name="address2"])[1]','VARCHAR(30)') AS [address2]
    , col.value('(Attribute[@name="city"])[1]','VARCHAR(30)') AS [city]
    , col.value('(Attribute[@name="state"])[1]','VARCHAR(30)') AS [state]
FROM @tbl AS tbl
    CROSS APPLY tbl.ColXML.nodes('/Attributes') AS tab(col);

输出

+------+--------------+-----------+--------+-------+
|  ID  |   address1   | address2  |  city  | state |
+------+--------------+-----------+--------+-------+
| 0001 | 301 Main St  | NULL      | Austin | NULL  |
| 0002 | 501 State St | Suite 301 | NULL   | Texas |
+------+--------------+-----------+--------+-------+
© www.soinside.com 2019 - 2024. All rights reserved.