从XML列中选择所有XML节点

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

我有一个带有XML列的表。每个条目的XML结构完全平坦,甚至没有父标记-这是一个条目的示例:

<tag1>1.22</tag1>
<tag3>5</tag3>
<tag12>-1.22</tag>

到目前为止,我已经能够做这样的事情:

SELECT CAST(xml_column AS NVARCHAR(MAX)) as XML_text

然后解析XML。或者,我显然可以编写xpath查询以将标签选择到列中,这是我想要的,除了有1000种可能的标签名称,而且我不想将它们全部写出来(并且可能会遗漏一个)。

总之,我该怎么做:

| ID | XML type column                |
| 1  | <tag1>1</tag1><tag2>2</tag2>   |
| 2  | <tag2>8</tag2><tag34>1</tag34> |

至此:

| ID | tag1 | tag2 | tag34 |
| 1  | 1    | 2    | NULL  |
| 2  | NULL | 8    | 1     |

对于我可以在数据集中找到的任何标签,而无需事先知道?

如果没有简单的方法,那很好,因为从那时起,我可以专注于MSSQL之外的解析技术。

sql-server xml tsql xquery sql-server-2016
1个回答
0
投票

通过使用XML数据类型方法和XQuery在MS SQL Server中非常简单。 SQL Server可以处理没有根元素的XML片段而没有任何问题。

您要实现的目标称为XML分解。

签出。

SQL

-- DDL and sample data population, start
DECLARE @tbl TABLE (ID INT IDENTITY PRIMARY KEY, xmldata XML);
INSERT INTO @tbl (xmldata) VALUES
(N'<tag1>1</tag1><tag2>2</tag2>')
,(N'<tag2>8</tag2><tag34>1</tag34>');
-- DDL and sample data population, end

-- Shred XML and convert it into a rectangular format
SELECT ID
    , col.value('(tag1/text())[1]','VARCHAR(10)') AS tag1 
    , col.value('(tag2/text())[1]','VARCHAR(10)') AS tag2
    , col.value('(tag3/text())[1]','VARCHAR(10)') AS tag3
    , col.value('(tag34/text())[1]','VARCHAR(10)') AS tag34
FROM @tbl AS tbl
    CROSS APPLY tbl.xmldata.nodes('.') AS tab(col);

输出

+----+------+------+------+-------+
| ID | tag1 | tag2 | tag3 | tag34 |
+----+------+------+------+-------+
|  1 | 1    |    2 | NULL | NULL  |
|  2 | NULL |    8 | NULL | 1     |
+----+------+------+------+-------+
© www.soinside.com 2019 - 2024. All rights reserved.