查询XML列的多行,将子节点提取到多行中
Querying multiple rows of an XML column to extract child nodes into multiple rows
在 SQL 服务器中,我有一个 table 和一个 XML 列,并且从每个 XML,我在父节点下有节点,我想select 节点中的每个值到每个 XML.
的单独行
我该如何完成?
下面是 table 外观的示例:
Name | Message
John | <User><Data><Valuelist><Value>123</Value><Value>456</Value><Value>789</Value><Value>654</Value></ValueList></Data></User>
Jack | <User><Data><ValueList><Value>555</Value><Value>455</Value></ValueList></Data></User>
Jane | <User><Data><Valuelist><Value>576</Value><Value>854</Value><Value>933</Value></ValueList></Data></User>
为了更清楚起见,下面是我尝试查询的“消息”列中的示例 XML:
<User>
<Data>
<ValueList>
<Value>123</Value>
<Value>456</Value>
<Value>789</Value>
<Value>654</Value>
</ValueList>
</Data>
</User>
下面是我希望在结果中看到的内容:
Name | Values
John | 123
John | 456
John | 789
John | 654
Jack | 555
Jack | 455
Jane | 576
Jane | 854
Jane | 933
我一直在尝试使用以下查询:
select t.Name, x.y.value('(Value)', 'nvarchar(10)') [Values]
from TABLE t
cross apply t.Message.nodes('//ValueList') as x(y)
但它给了我以下错误:
'value()' requires a singleton (or empty sequence), found operand of type 'xdt:untypedAtomic *'
我只能 select 使用以下值之一:
select t.Name, x.y.value('(Value[1])', 'nvarchar(10)') [Values]
from TABLE t
cross apply t.Message.nodes('//ValueList') as x(y)
我一直在谷歌上搜索,但找不到我想要做的事情。
我应该在这里做什么?
我的SQL服务器版本是2016 SP2。
提前致谢!
请尝试以下解决方案。
SQL
-- DDL and sample data population, start
DECLARE @tbl table (ID INT IDENTITY PRIMARY KEY, Name VARCHAR(20), Message XML);
INSERT INTO @tbl (Name, Message) VALUES
('John', N'<User><Data><ValueList><Value>123</Value><Value>456</Value><Value>789</Value><Value>654</Value></ValueList></Data></User>'),
('Jack', N'<User><Data><ValueList><Value>555</Value><Value>455</Value></ValueList></Data></User>'),
('Jane', N'<User><Data><ValueList><Value>576</Value><Value>854</Value><Value>933</Value></ValueList></Data></User>');
-- DDL and sample data population, end
SELECT t.ID, t.Name
, c.value('(./text())[1]', 'nvarchar(10)') AS [Values]
FROM @tbl AS t
CROSS APPLY Message.nodes('/User/Data/ValueList/Value') as t1(c);
输出
+----+------+--------+
| ID | Name | Values |
+----+------+--------+
| 1 | John | 123 |
| 1 | John | 456 |
| 1 | John | 789 |
| 1 | John | 654 |
| 2 | Jack | 555 |
| 2 | Jack | 455 |
| 3 | Jane | 576 |
| 3 | Jane | 854 |
| 3 | Jane | 933 |
+----+------+--------+
在 SQL 服务器中,我有一个 table 和一个 XML 列,并且从每个 XML,我在父节点下有节点,我想select 节点中的每个值到每个 XML.
的单独行我该如何完成?
下面是 table 外观的示例:
Name | Message
John | <User><Data><Valuelist><Value>123</Value><Value>456</Value><Value>789</Value><Value>654</Value></ValueList></Data></User>
Jack | <User><Data><ValueList><Value>555</Value><Value>455</Value></ValueList></Data></User>
Jane | <User><Data><Valuelist><Value>576</Value><Value>854</Value><Value>933</Value></ValueList></Data></User>
为了更清楚起见,下面是我尝试查询的“消息”列中的示例 XML:
<User>
<Data>
<ValueList>
<Value>123</Value>
<Value>456</Value>
<Value>789</Value>
<Value>654</Value>
</ValueList>
</Data>
</User>
下面是我希望在结果中看到的内容:
Name | Values
John | 123
John | 456
John | 789
John | 654
Jack | 555
Jack | 455
Jane | 576
Jane | 854
Jane | 933
我一直在尝试使用以下查询:
select t.Name, x.y.value('(Value)', 'nvarchar(10)') [Values]
from TABLE t
cross apply t.Message.nodes('//ValueList') as x(y)
但它给了我以下错误:
'value()' requires a singleton (or empty sequence), found operand of type 'xdt:untypedAtomic *'
我只能 select 使用以下值之一:
select t.Name, x.y.value('(Value[1])', 'nvarchar(10)') [Values]
from TABLE t
cross apply t.Message.nodes('//ValueList') as x(y)
我一直在谷歌上搜索,但找不到我想要做的事情。
我应该在这里做什么?
我的SQL服务器版本是2016 SP2。
提前致谢!
请尝试以下解决方案。
SQL
-- DDL and sample data population, start
DECLARE @tbl table (ID INT IDENTITY PRIMARY KEY, Name VARCHAR(20), Message XML);
INSERT INTO @tbl (Name, Message) VALUES
('John', N'<User><Data><ValueList><Value>123</Value><Value>456</Value><Value>789</Value><Value>654</Value></ValueList></Data></User>'),
('Jack', N'<User><Data><ValueList><Value>555</Value><Value>455</Value></ValueList></Data></User>'),
('Jane', N'<User><Data><ValueList><Value>576</Value><Value>854</Value><Value>933</Value></ValueList></Data></User>');
-- DDL and sample data population, end
SELECT t.ID, t.Name
, c.value('(./text())[1]', 'nvarchar(10)') AS [Values]
FROM @tbl AS t
CROSS APPLY Message.nodes('/User/Data/ValueList/Value') as t1(c);
输出
+----+------+--------+
| ID | Name | Values |
+----+------+--------+
| 1 | John | 123 |
| 1 | John | 456 |
| 1 | John | 789 |
| 1 | John | 654 |
| 2 | Jack | 555 |
| 2 | Jack | 455 |
| 3 | Jane | 576 |
| 3 | Jane | 854 |
| 3 | Jane | 933 |
+----+------+--------+