SQL:如何通过筛选XML列中的值来查找行

SQL:如何通过筛选XML列中的值来查找行,xml,tsql,xpath,sql-server-2012,xquery,Xml,Tsql,Xpath,Sql Server 2012,Xquery,我有一个字段具有XML数据类型,下面是我保存在该字段中的XML数据示例。现在,我想使用下面的查询来选择具有1个内部标记的数据,但没有结果 SELECT [SettingsID] ,[XMLData] FROM Settings Where [XMLData].exist('/Settings/SiteId/text()[contains(.,"1")]') =1 XMLDATA sample <Settings xmlns:xsi="http://www.w3.org/

我有一个字段具有XML数据类型,下面是我保存在该字段中的XML数据示例。现在,我想使用下面的查询来选择具有1个内部标记的数据,但没有结果

SELECT [SettingsID]
      ,[XMLData]
FROM Settings
Where [XMLData].exist('/Settings/SiteId/text()[contains(.,"1")]') =1 


XMLDATA sample

<Settings xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <SiteId>1</SiteId>
  <ModuleId xsi:nil="true" />
  <TabId xsi:nil="true" />
  <Version>0</Version>
</Settings>

有人对此有想法吗?

你问题的标题可能会误导人

我认为您不是在寻找全文搜索,而是在寻找合适的XQuery来查找具有给定条件的条目

试试这个:

DECLARE @mockupTable TABLE(SettingsID INT IDENTITY, XMLData XML);
INSERT INTO @mockupTable VALUES
 (N'<Settings xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <SiteId>1</SiteId>
  <ModuleId xsi:nil="true" />
  <TabId xsi:nil="true" />
  <Version>0</Version>
</Settings>')
,(N'<Settings xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <SiteId>2</SiteId>
  <ModuleId xsi:nil="true" />
  <TabId xsi:nil="true" />
  <Version>0</Version>
</Settings>');
只需使用sql即可将1引入查询:variable@SomeIntVariable而不是1

使现代化 要尽可能地创建此名称空间,可以使用//和*:的深度搜索来省略任何名称空间:

SELECT[SettingsID]
      ,[XMLData]
FROM @mockupTable
Where [XMLData].exist('//*:SiteId[text()="1"]') =1;

也许有点傻,但我很理解你的问题,这可能很好:

SELECT [SettingsID],[XMLData]
FROM Settings
Where [XMLData] LIKE '%<SiteId>1</SiteId>%' 

您使用的是哪种数据库管理系统?该查询是特定于产品的。@jarlh,ms sql2012@crisgomez我刚刚用我的模型表测试了你的查询,看到了答案,它似乎起作用了。。。请注意,该contains将在任何文本中找到包含1的任何文本position@crisgomez我刚刚改写了你的标题-如果我没有正确理解,请检查并回滚更改!谢谢@Shnugo,这是有效的,但是当我使用实际的表时,这是无效的。不知道为什么。@crisgomez不工作意味着什么?错误没有结果?是否有您没有提到的名称空间?结构可能不同吗?您没有发布完整的示例吗?@crisgomez尝试将XPath设置为[XMLData]所在的位置。exist'/*:SiteId[text=1]'=1;这将执行深度搜索,忽略父节点并忽略名称空间…它可以工作!Shnugo,非常感谢!顺便说一下,我不工作的意思是没有结果。@crisgomez太棒了!在本例中,我假设给定的示例XML在某种程度上被简化了,因此XPath没有命中。Hi P.ejH,我们有相同的实现,因为性能问题,我将其更改为全文搜索。根据示例代码,给定的列是原生XML。这类人需要先转换到NVARCHARMAX,这在这里非常昂贵…@crisgomez正确的XML查询with.exist是f-当然比全文搜索还快。。。
SELECT[SettingsID]
      ,[XMLData]
FROM @mockupTable
Where [XMLData].exist('//*:SiteId[text()="1"]') =1;
SELECT [SettingsID],[XMLData]
FROM Settings
Where [XMLData] LIKE '%<SiteId>1</SiteId>%'