Извлечение атрибутов из полей XML в таблице SQL Server 2008
у меня есть таблица с несколькими столбцами, один из которых является . У меня нет пространства имен для использования в запросе. 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>')
Желаемые Результаты
Name Info.x Info.y Info
----- ------- ------- -------
one 42 99 Red
two 27 72 Blue
three 16 51 Green
four 12 37 Yellow
Частично Работает
select Name, xml_data.query('/data/info/.').value('.', 'varchar(10)') as [Info]
from #temp
возвращает Name
и Info
столбцы. Я не могу понять, как извлечь значения атрибутов без использования пространства имен. Например, следующие запросы возвращают ошибки:
запрос 1
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
запрос 2
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 *'
запрос 3
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
вопрос
как вы пишете запрос для возврата данных регулярного столбца и значений элемента + атрибута из xml
столбец в той же таблице?
1 ответов
сразу после того, как я разместил вопрос, я наткнулся на это ответ. Не знаю, почему я не мог найти его в предыдущих поисков. Это был ответ, который я искал. Вот запрос, который работает:
запрос
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
результат
Name Info.x Info.y Info
------- -------- -------- ---------
one 42 99 Red
two 27 72 Blue
three 16 51 Green
four 12 37 Yellow
.
------ редактировать [2014-01-29] ------
я нашел еще один случай, который стоит добавить к этому ответу. Учитывая несколько <info>
элементы внутри <data>
элемент, it можно вернуть все <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
в этом примере возвращается следующий набор данных:
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