2013-04-10 80 views
4

我有一个带有XML数据类型列的数据库表。列包含的值是这样的:SQL Server XML数据类型LIKE比较

<NameValuePairCollection> 
    <NameValuePair Name="Foo" Value="One" /> 
    <NameValuePair Name="Bar" Value="Two" /> 
    <NameValuePair Name="Baz" Value="Three" /> 
</NameValuePairCollection> 

我想查询在XML数据类型列有一个"Foo""One"值的所有行。我无法创建合适的XQuery来过滤结果。

我发现了几个相关的SO问题,这些问题在我的尝试中帮助了我,但仍然无法实现。

How can I query a value in SQL Server XML column
Use a LIKE statment on 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) *' 

UPDATE(以回应@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 *' 
+0

[在SQL Server XML数据类型上使用LIKE语句](https://stackoverflow.com/questions/1832987/use-a-like-statement-on-sql-server-xml-datatype) – Squazz 2017-09-06 11:43:04

回答

2

如果你想选择Value属性与[XmlDataColumn].value(...) XPath表达式整个NameValuePair元素代替的价值,这应该工作:

/NameValuePairCollection/NameValuePair[@Name="Foo"]/@Value 

你的表达仅检查NameValuePair是否具有属性Value

如果没有使用正确的名称的多个元素,并要检查其中是否具有价值"One",您可以使用exist(...)方法:

where [XmlDataColumn].exist(
    '/NameValuePairCollection/NameValuePair[@Name="Subject" and @Value="One"]') = 1 
+0

I试过这个,但它仍然没有工作。有关更多详细信息,请参阅编辑我的问题。 – 2013-04-10 20:11:24

+0

有多个NameValuePair与你正在寻找的Name?我会更新我的答案。 – 2013-04-10 20:26:30

+0

我不认为有多个元素具有相同的“名称”,但我会尝试替代解决方案,看看会发生什么。 – 2013-04-10 20:32:26

1

另一种选择是投XML为varchar ,然后搜索给定的字符串,就好像XML获得一个varchar字段一样。

SELECT * 
FROM Table 
WHERE CAST(Column as nvarchar(max)) LIKE '%Name="Foo" Value="One"%' 

我喜欢这个解决方案,因为它是干净的,容易记忆,很难陷入困境,并且可以作为一个where子句的一部分。

它不像Leo提供的答案那样动态和完整,但取决于具体情况,它可能是一种“快速”“肮脏”的方式来获取所需的数据。