Как сравнение в SQL Server XML datatype
У меня есть таблица БД со столбцом типа данных XML. Столбец содержит следующие значения:
<NameValuePairCollection>
<NameValuePair Name="Foo" Value="One" />
<NameValuePair Name="Bar" Value="Two" />
<NameValuePair Name="Baz" Value="Three" />
</NameValuePairCollection>
Я пытаюсь запросить все строки, в которых столбец XML datatype имеет значение "One"
для "Foo"
. У меня возникли проблемы с созданием соответствующего XQuery для фильтрации результатов.
Как я могу запросить значение в столбце SQL Server XML
используйте подобное утверждение на SQL Server XML Datatype
Вот SQL, который у меня есть до сих пор:
select *
from MyTable
where [XmlDataColumn].value('((/NameValuePairCollection/NameValuePair)[@Name="Foo"])[@Value]', 'varchar(max)') = 'One'
order by ID desc
Вот ошибка, которую я получаю прямо сейчас:
XQuery [MyTable.XmlDataColumn.value()]: Cannot atomize/apply data() on expression that contains type 'NameValuePair' within inferred type 'element(NameValuePair,#anonymous) *'
Обновление (В ответ на предложение @LeoWörteler по)
Основываясь на вашем ответе, я изменил свой SQL на следующий:
select *
from MyTable with(nolock)
where [XmlDataColumn].value('/NameValuePairCollection/NameValuePair[@Name="Subject"]/@Value', 'varchar(max)') = 'One'
order by ID desc
Но это все равно не работает. Я получаю следующую ошибку:
XQuery [MyTable.XmlDataColumn.value()]: 'value()' requires a singleton (or empty sequence), found operand of type 'xs:string *'
2 ответа:
Если вы хотите выбрать значение атрибута
Value
вместо целого элементаNameValuePair
с выражением XPath в[XmlDataColumn].value(...)
, это должно работать:/NameValuePairCollection/NameValuePair[@Name="Foo"]/@Value
Ваше выражение проверяет только, имеет ли
NameValuePair
атрибутValue
.Если существует несколько элементов с правильным именем и вы хотите проверить, имеет ли какой-либо из них значение
"One"
, Вы можете использоватьexist(...)
метод:where [XmlDataColumn].exist( '/NameValuePairCollection/NameValuePair[@Name="Subject" and @Value="One"]') = 1
Другой вариант-привести XML как varchar, а затем искать заданную строку, как если бы XML был полем varchar.
SELECT * FROM Table WHERE CAST(Column as nvarchar(max)) LIKE '%Name="Foo" Value="One"%'
Мне нравится это решение, поскольку оно чистое, легко запоминается, трудно запутывается и может использоваться как часть предложения where.
Это не так динамично и полно, как ответ, предоставленный Лео, но в зависимости от обстоятельств это может быть "быстрый и грязный" способ получить необходимые данные.