【问题标题】:LIKE comparison in SQL Server XML datatypeSQL Server XML 数据类型中的 LIKE 比较
【发布时间】:2013-04-02 19:04:00
【问题描述】:

我有一个带有 XML 数据类型列的 DB 表。该列包含如下值:

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

我正在尝试查询 XML 数据类型列的值为 "One" 的所有行,以获取 "Foo"。我无法创建适当的 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) *'

更新(回应@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 *'

【问题讨论】:

标签: sql sql-server xml xquery


【解决方案1】:

如果您想使用[XmlDataColumn].value(...) 中的 XPath 表达式选择 Value 属性的值而不是整个 NameValuePair 元素,这应该可以:

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

您的表达式仅检查NameValuePair 是否具有Value 属性。

如果有多个具有正确名称的元素,并且您想检查其中任何一个的值是否为"One",则可以使用exist(...) 方法:

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

【讨论】:

  • 我试过了,但还是不行。有关详细信息,请参阅我的问题的编辑。
  • 您要查找的Name 是否有多个NameValuePairs?我会针对这种情况更新我的答案。
  • 我认为没有多个元素具有相同的 Name,但我会尝试您的替代解决方案,看看会发生什么。
  • 我必须有记录,其中有多个 NameValuePair 元素的“名称”属性为 "Foo",因为您的第二个解决方案对我有用。非常感谢您的帮助!
【解决方案2】:

另一种选择是将 XML 转换为 varchar,然后搜索给定的字符串,就像 XML vas 是 varchar 字段一样。

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

我喜欢这个解决方案,因为它干净、易于记忆、不易搞砸,并且可以用作 where 子句的一部分。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多