2011-12-11 7 views
5

私は、SQL Serverのexist()value()方法2008SQL ServerのXML(存在)

を使用して、いくつかの問題を抱えている私のXMLは次のようになります。この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> 

、私が書く必要がありますSELECT節では、query(),value()およびexist()を最低2回使用します。 WHERE句は何の効果もないように見えるので、同じSELECTquery()exist()を使用することすらできません。

例えば、私はタイプSFと書籍の子であるすべての<branch>の要素を取得したいのですが、

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

はすべて<branch>要素、対象からのものだけでなくを取得するselect文本。私は自分の選択に何が間違っているのか理解できません。また、私は(SQL、XMLでSELECT文を入れ子にしていると、それも可能でしょうか?)同じ選択にquery()exist()value()の小さな例をいただければ幸いです

答えて

7

さて、ここであなたのXPath式は、「犯人」は次のとおりです。

query('//branch') 

これは、次のように書かれています。選択文書すべて<branch>ノード。それは本当にあなたがやっていることをやっているだけです...。

この質問には何が間違っていますか?属性としてtype="SF"を持って<book>ノードのすべての<branch>サブノードを取得します

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

....あなたは同じ文であなたのquery()exist()value()すべてを達成しようとしている何

??おそらく、それはもっと簡単に行うことができます....

また、私はあなたが誤って解釈していると思うのは、SQL Server XQueryで何をしますか。あなたがここにあなたの声明がある場合: - あなたは、テーブルから行を選択している - 適用しない

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

をあなたは基本的にXMLDataに格納されたXMLが<book type=.....>ノードが含まれていdbo.TableAからすべての行を取得するために、SQL Serverを言っていますXMLData列の内容への選択...

+0

私は欲しいものではありませんが、同じ文でquery()、value()、exist()の両方を使用する必要があります。そのため、T-SQL、SELECT ...のようなフィルタリングをしたいのですが... WHERE ...可能な場合は、ネストされたSELECT文のようなものかもしれません。私はちょうどそのようなsmthを達成する方法の例をしたい – joanna

3

入力したXMLはexist文には表示されません。複数のXML文を持っていて、それが何らかの価値を含んでいるものを見つけ出す必要があった場合、その文はより適切なものになりました。

指定したwhere節は、条件が存在するかどうかをチェックし、存在する場合は、条件が真であるものだけでなく、すべてbranches要素を選択します。

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

をしかし、ここであなたはすべての3つのいずれかで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) 
+0

あなたが提供したSELECTは私が必要とするものに近い、tnxです。 1つの最後の問題は...それは可能なので、私はvalue()、exist()とquery()を2回使うことができるようにSELECT ... WHERE x =(SELECT..WHERE)のようなものを持つことができますか?基本的には、いくつかの値をフィルタリングするselect(3つの関数すべて)と、フィルタリングされたノードを使用する別のものです。 – joanna

0

これが遅くなっても謝罪しましたが、私はこの投稿を見ました。

XMLを使用すると、クロス・アプライ・オペレータを使用して必要なノードにフィルタをかけ、返されたノードから問合せを選択する方が効率的です。子ノードを照会するには、ルートも含める必要があります。クエリではこの場合は//ブランチではなく.//ブランチになります。

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

あなたはまだ希望このことができますしたい場合は句が存在するが、これは実際には、追加の不要なオーバーヘッドが追加されます

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

を追加することができます。 D

関連する問題