查询XML列的值

时间:2014-08-21 09:24:15

标签: sql sql-server

我有一个带有XML列的SQL Server表,它包含类似这样的数据:

<Query>
  <QueryGroup>
    <QueryRule>
      <Attribute>Integration</Attribute>
      <RuleOperator>8</RuleOperator>
      <Value />
      <Grouping>OrOperator</Grouping>
    </QueryRule>
    <QueryRule>
      <Attribute>Integration</Attribute>
      <RuleOperator>5</RuleOperator>
      <Value>None</Value>
      <Grouping>AndOperator</Grouping>
    </QueryRule>
  </QueryGroup>
</Query>

每个QueryRule只有一个Attribute,但每个QueryGroup可以有许多QueryRules。每个Query也可以有许多QueryGroup。

我需要能够提取具有一个或多个具有特定属性和值的QueryRule的所有记录。

SELECT * 
FROM QueryBuilderQueries 
WHERE [the xml contains any value=X where the attribute is either Y or Z]

我已经研究了如何检查特定的QueryRule,但没有&#34;任何&#34;。

SELECT
  Query
FROM
  QueryBuilderQueries
WHERE
  Query.value('(/Query/QueryGroup/QueryRule/Value)[1]', 'varchar(max)') like 'UserToFind'
  AND Query.value('(/Query/QueryGroup/QueryRule/Attribute)[1]', 'varchar(max)') in ('FirstName', 'LastName')

3 个答案:

答案 0 :(得分:1)

您可以使用两个exist()。一个用于检查值,另一个用于检查属性。

select Q.Query
from dbo.QueryBuilderQueries as Q
where Q.Query.exist('/Query/QueryGroup/QueryRule/Value/text()[. = "UserToFind"]') = 1 and
      Q.Query.exist('/Query/QueryGroup/QueryRule/Attribute/text()[. = ("FirstName", "LastName")]') = 1

如果您在搜索值时确实需要like等效,则可以使用contains()

select Q.Query
from dbo.QueryBuilderQueries as Q
where Q.Query.exist('/Query/QueryGroup/QueryRule/Value/text()[contains(., "UserToFind")]') = 1 and
      Q.Query.exist('/Query/QueryGroup/QueryRule/Attribute/text()[. = ("FirstName", "LastName")]') = 1

答案 1 :(得分:0)

根据http://technet.microsoft.com/pl-pl/library/ms178030%28v=sql.110%29.aspx

&#34; XQuery必须至多返回一个值&#34;

如果你非常肯定,例如你的XML让我们说最多10个QueryRule你可以使用WHILE来循环所有内容,同时将结果放到临时表中吗?

也许下面可以帮助你

CREATE TABLE #temp(
Query type)

DECLARE @i INT
SET @i = 1
WHILE @i >= 10
BEGIN
INSERT INTO #temp
    SELECT
        Query
    FROM QueryBuilderQueries
    WHERE Query.value('(/Query/QueryGroup/QueryRule/Value)[@i]', 'varchar(max)') LIKE 'UserToFind'
    AND Query.value('(/Query/QueryGroup/QueryRule/Attribute)[@i]', 'varchar(max)') IN ('FirstName', 'LastName')

  @i = @i + 1
END

SELECT
    *
FROM #temp

答案 2 :(得分:0)

遗憾的是,SQL Server(我使用的是2008)不支持某些与字符串相关的XQuery函数,例如fn:matches,...如果它支持这样的函数,我们可以直接在XQuery表达式中查询确定是否有 任何 。但是我们还有另一种方法。这是通过将所有可能的值转换为相应的SQL行来使用SQL的WHERELIKE功能进行搜索/过滤。在使用nodes()方法(用于XML数据)进行一些体验之后,我认为这是最好的选择:

select *
from QueryBuilderQueries 
where exists( select *
              from Query.nodes('//QueryRule') as v(x)
              where LOWER(v.x.value('(Attribute)[1]','varchar(max)')) 
                                          in ('firstname','lastname')
                    and v.x.value('(Value)[1]','varchar(max)') like 'UserToFind')