Тип XML сервера SQL Выберите, где атрибут = X из любого тега - PullRequest
1 голос
/ 24 августа 2011
select *
from tablename
where CONVERT(xml, Sections).value('(/sections/section/@value)[1]', 'varchar(1)') = 'f'

правильно извлечет запись со следующим значением в столбце Разделы:

<sections><section value="f" priority="4" /><section value="a" priority="4" /></sections>

Но пропускает это:

<sections><section value="w" priority="4" /><section value="f" priority="4" /></sections>

Очевидно, что это проблема "/sections/section/@value)[1]", но я не понимаю синтаксис, и Google не слишком помог. Я нашел некоторый код, который позволил мне зайти так далеко, но я не знаю, как его изменить, чтобы он просматривал все теги, а не только первый. Я попытался сбросить [1], но это дало следующую ошибку:

XQuery [value()]: 'value()' requires a singleton (or empty sequence), found operand of type 'xdt:untypedAtomic *'

Ответы [ 2 ]

2 голосов
/ 24 августа 2011

Вы можете использовать exist () .

select *
from tablename
where CONVERT(xml, Sections).exist('/sections/section[@value = "f"]') = 1

Если вы хотите использовать динамическое значение вместо жестко закодированного f в запросе, вы можете использовать sql: variable () .

declare @Value varchar(10) = 'f'

select *
from tablename
where CONVERT(xml, Sections).exist('/sections/section[@value = sql:variable("@Value")]') = 1
1 голос
/ 24 августа 2011

Если у вас есть несколько записей тега XML, вам нужно использовать метод .nodes() XQuery:

select 
    *,
    Sections(Section).value('(@value)[1]', 'varchar(1)') 
from tablename
cross apply CONVERT(xml, Sections).nodes('/sections/section') AS Sections(Section)

При этом вы создаете «псевдотаблица» с именем Sections(Section), которая содержит одну строку XML для каждого элемента, соответствующего вашему XPath (для каждого <section> в <sections>). Затем вы можете обратиться к этой псевдотаблице и извлечь отдельные биты информации из этих «строк» ​​XML, используя обычный .value() метод

...