Jam*_* L. 28 xml-attribute sql-server-2008
我有一个包含多个列的表,其中一xml列是一列.我没有在查询中使用的命名空间.对于所有记录,XML数据始终是相同的结构.
create table #temp (id int, name varchar(32), xml_data xml)
insert into #temp values
(1, 'one', '<data><info x="42" y="99">Red</info></data>'),
(2, 'two', '<data><info x="27" y="72">Blue</info></data>'),
(3, 'three', '<data><info x="16" y="51">Green</info></data>'),
(4, 'four', '<data><info x="12" y="37">Yellow</info></data>')
Run Code Online (Sandbox Code Playgroud)
Name Info.x Info.y Info
----- ------- ------- -------
one 42 99 Red
two 27 72 Blue
three 16 51 Green
four 12 37 Yellow
Run Code Online (Sandbox Code Playgroud)
select Name, xml_data.query('/data/info/.').value('.', 'varchar(10)') as [Info]
from #temp
Run Code Online (Sandbox Code Playgroud)
它返回Name和Info列.我无法弄清楚如何在不使用命名空间的情况下提取属性值.例如,以下查询返回错误:
select Name, xml_data.query('/data/info/@x') as [Info]
from #temp
Msg 2396, Level 16, State 1, Line 12
XQuery [#temp.xml_data.query()]: Attribute may not appear outside of an element
Run Code Online (Sandbox Code Playgroud)
select Name, xml_data.value('/data/info/@x', 'int') as [Info]
from #temp
Msg 2389, Level 16, State 1, Line 12
XQuery [#temp.xml_data.value()]: 'value()' requires a singleton (or empty sequence), found operand of type 'xdt:untypedAtomic *'
Run Code Online (Sandbox Code Playgroud)
select Name, xml_data.query('/data/info/.').value('@x', 'int') as [Info]
from #temp
Msg 2390, Level 16, State 1, Line 9
XQuery [value()]: Top-level attribute nodes are not supported
Run Code Online (Sandbox Code Playgroud)
如何编写查询以从xml同一个表中的列返回常规列数据和元素+属性值?
Jam*_* L. 39
就在我发布问题之后,我偶然发现了这个问题.不知道为什么我在以前的搜索中找不到它.这是我正在寻找的答案.这是有效的查询:
select Name
,xml_data.value('(/data/info/@x)[1]', 'int') as [Info.x]
,xml_data.value('(/data/info/@y)[1]', 'int') as [Info.y]
,xml_data.value('(/data/info/.)[1]', 'varchar(10)') as [Info]
from #temp
Run Code Online (Sandbox Code Playgroud)
Name Info.x Info.y Info
------- -------- -------- ---------
one 42 99 Red
two 27 72 Blue
three 16 51 Green
four 12 37 Yellow
Run Code Online (Sandbox Code Playgroud)
.
我找到了另一个值得添加到这个答案的案例.给定<info>元素中的多个元素<data>,可以<info>使用cross apply以下命令返回所有节点:
create table #temp (id int, name varchar(32), xml_data xml)
insert into #temp values
(1, 'one', '<data><info x="42" y="99">Red</info><info x="43" y="100">Pink</info></data>'),
(2, 'two', '<data><info x="27" y="72">Blue</info><info x="28" y="73">Light Blue</info></data>'),
(3, 'three', '<data><info x="16" y="51">Green</info><info x="17" y="52">Orange</info></data>'),
(4, 'four', '<data><info x="12" y="37">Yellow</info><info x="13" y="38">Purple</info></data>')
select Name
,C.value('@x', 'int') as [Info.x]
,C.value('@y', 'int') as [Info.y]
,C.value('.', 'varchar(10)') as [Info]
from #temp cross apply
#temp.xml_data.nodes('data/info') as X(C)
drop table #temp
Run Code Online (Sandbox Code Playgroud)
此示例返回以下数据集:
Name Info.x Info.y Info
--------- ----------- ----------- ----------
one 42 99 Red
one 43 100 Pink
two 27 72 Blue
two 28 73 Light Blue
three 16 51 Green
three 17 52 Orange
four 12 37 Yellow
four 13 38 Purple
Run Code Online (Sandbox Code Playgroud)