解析XML并通过SQL Query生成新行

时间:2016-08-11 09:05:00

标签: sql-server xml-parsing

我在SQL表中以下面的格式输入数据:

ID    Text
 1    <Key><Name>Adobe</Name><Display>Ado</Display></Key><Key>.....</Key>
 2    <Key><Name></Name><Display>Microsoft</Display><Version>1.1</Version></Key>

每个ID可以有多个密钥。上述格式的表中可能有几千行。我以下面的格式生成最终的sql输出

ID  Name  Display    Version
1   Adobe Ado       
1   xyz   yz         1.2
2         Microsoft  1.1

我使用以下查询来解析Text列,但将所有数据放在一行中。如何将该数据分成多行,如上所示。

SELECT 
    CAST(CAST(Text AS XML).query('data(/Key/Name)') AS VARCHAR(MAX)) AS Name,
    CAST(CAST(Text AS XML).query('data(/Key/Display)') as VARCHAR(MAX)) AS DisplayName,
    CAST(CAST(Text AS XML).query('data(/Key/Version)') AS VARCHAR(MAX)) AS Version
FROM 
    ABC where ID = 1

目前,我一次为每个ID运行此查询。有没有办法一起运行所有ID。此外,还有其他有效的方法来获得所需的输出。

1 个答案:

答案 0 :(得分:0)

以下是示例:

-- Sample demonstrational schema
declare @t table (
    Id int primary key,
    TextData nvarchar(max) not null
);

insert into @t
values
(1, N'<Key><Name>Adobe</Name><Display>Ado</Display></Key><Key><Name>xyz</Name><Display>yz</Display><Version>1.2</Version></Key>'),
(2, N'<Key><Name></Name><Display>Microsoft</Display><Version>1.1</Version></Key>');

-- The actual query
with cte as (
    select t.Id, cast(t.TextData as xml) as [XMLData]
    from @t t
)
select c.Id,
    k.c.value('./Name[1]', 'varchar(max)') as [Name],
    k.c.value('./Display[1]', 'varchar(max)') as [DisplayName],
    k.c.value('./Version[1]', 'varchar(max)') as [Version]
from cte c
    cross apply c.XMLData.nodes('/Key') k(c);

可以使用CTE(或等效子查询)中的就地演员/转换来纠正不同的类型。