我在SQL Server 2008中使用exist()value()方法时遇到一些问题。

我的XML看起来像这样:

<?xml version="1.0" encoding="UTF-8"?>
<library>
    <branches>
        <branch>
            <codelib>1</codelib>
            <name>Campus</name>
        </branch>
        <branch>
            <codelib>2</codelib>
            <name>47th</name>
        </branch>
        <branch>
            <codelib>3</codelib>
            <name>Mall</name>
        </branch>              
    </branches>
    <books>
        <book type="SF">
            <codb>11</codb>
            <title>Robots</title>
            <authors>
                <author>author1 robots</author>
                <author>author2 robots</author>
            </authors>
            <price>10</price>
            <stocks>
                <branch codelib="1" amount="10"/>
                <branch codelib="2" amount="5"/>
                <branch codelib="4" amount="15"/>
            </stocks>
            <from>20</from>
            <to>30</to>
        </book>
        <book type="poetry">
            <codb>12</codb>
            <title>Poetry book</title>
            <authors>
                <author>AuthorPoetry</author>
            </authors>
            <price>14</price>
            <stocks>
                <branch codelib="1" amount="7"/>
                <branch codelib="2" amount="5"/>
            </stocks>
            <from>25</from>
            <to>40</to>
        </book>       
        <book type="children">
            <codb>19</codb>
            <title>Faitytales</title>
            <authors>               
                <author>AuthorChildren</author>             
            </authors>
            <price>20</price>
            <stocks>
                <branch codelib="1" amount="10"/>
                <branch codelib="3" amount="55"/>
                <branch codelib="4" amount="15"/>
            </stocks>
            <from>70</from>
            <to>75</to>
        </book>       
        <book type="literature">
            <codb>19</codb>
            <title>T</title>
            <authors>
                <author>A</author>                
            </authors>
            <price>17</price>
            <stocks>
                <branch codelib="1" amount="40"/>
            </stocks>
            <from>85</from>
            <to>110</to>
        </book>
    </books>
</library>

鉴于这个XML,我必须编写一个SELECT子句,每个子句最少使用query()value()exist() 2次。 我甚至exist()在同一个SELECT使用query()exist() ,因为看起来WHERE子句没有任何效果。

例如,我想检索作为书籍子级的所有<branch>元素,类型为SF ,但是select语句

  declare @genre varchar(15)
  set @genre = 'SF'
  SELECT XMLData.query('//branch') from TableA
  WHERE XMLData.exist('//book[./@type = sql:variable("@genre")]') = 1

检索所有<branch>元素,而不仅仅是目标书籍中的元素。 我无法弄清楚我的选择有什么问题。 另外,我会很感激在同一个select中使用query()exist()value()一个小例子(是否可以在sql xml中使用嵌套的select语句?)

===============>>#1 票数:7

那么,你的XPath表达式就是“罪魁祸首”:

query('//branch')

这表示:从整个文档中选择所有 <branch>节点。 它正在做你要告诉它的事情,真的......

这个查询有什么问题?

SELECT 
    XMLData.query('/library/books/book[@type=sql:variable("@genre")]//branch')
FROM dbo.TableA

这将检索具有type="SF"作为属性的<book>节点的所有<branch>子节点....

你想用同一个语句中的query()exist()value()来实现什么? 很可能,它可以做得更轻松....

另外:我认为你误解了SQL Server XQuery中的.exist() 如果您在此声明:

 SELECT (some columns)
 FROM dbo.TableA
 WHERE XMLData.exist('//book[@type = sql:variable("@genre")]') = 1

你基本上是告诉SQL Server来检索所有行dbo.TableA其中存储在XML XMLData包含<book type=.....>节点-你从表中选择数据- 适用选择到XMLData专栏内容......

===============>>#2 票数:3

您提供的XML不适用于exist语句。 如果您有多个XML语句并且需要找到包含某些值的语句,那么该语句将更具相关性。

您提供的where子句只检查条件是否存在,如果存在,则选择所有branches元素,而不仅仅是条件为true的元素。 例如,以下(显然)不返回任何内容:

SELECT @xmldata.query('//branch') from TableA
 WHERE @xmldata.exist('//book[./@type = "BLAH"]') = 1

但是这里有一些东西可以证明你可以在一个select语句中使用所有三个。

SELECT T.c.query('./title').value('.', 'varchar(250)') as title, 
       T.c.exist('.[@type eq "SF"]') as IsSF
  from @xmldata.nodes('//book') T(c)

===============>>#3 票数:0

使用交叉应用运算符过滤到所需节点,然后从返回的节点中选择查询,使用XML进行过滤会更有效。 要查询子节点,还需要包含根节点。 在查询中所以在这种情况下.//branch而不是// branch。

declare @genre varchar(15) = 'SF'
select l.query('.//branch') from TableA
cross apply XmlData.nodes('library/books/book[@type=sql:variable("@genre")]') n (l)

如果需要,您仍然可以添加exists子句,但这实际上会增加额外的不必要开销

WHERE XMLData.exist('//book[./@type = sql:variable("@genre")]') = 1

希望这可以帮助。 d

  ask by joanna translate from so

未解决问题?本站智能推荐: