Allgemeine Einsatzgebiete für XQuery

Dieses Thema stellt allgemeine Beispiele für die Verwendung von XQuery zur Verfügung.

Beispiele

A. Abfragen von Katalogbeschreibungen zum Suchen nach Produkten und Gewichtungen

Die folgende Abfrage gibt die Produktmodell-IDs und (sofern vorhanden) die Gewichtungen aus der Produktkatalogbeschreibung zurück. Die Abfrage ergibt eine XML-Konstruktion mit der folgenden Form:

<Product ProductModelID="…">
  <Weight>…</Weight>
</Product>

Im Folgenden wird die Abfrage aufgeführt:

SELECT CatalogDescription.query('
declare namespace p1="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription";
  <Product  ProductModelID="{ (/p1:ProductDescription/@ProductModelID)[1] }">
     { 
       /p1:ProductDescription/p1:Specifications/Weight 
     } 
  </Product>
') as Result
FROM Production.ProductModel
WHERE CatalogDescription is not null

Beachten Sie in der vorherigen Abfrage Folgendes:

  • Das namespace-Schlüsselwort im XQuery-Prolog definiert ein Namespacepräfix, das im Body-Teil der Abfrage verwendet wird.
  • Der Body-Teil der Abfrage bewirkt die Konstruktion des erforderlichen XML-Codes.
  • In der WHERE-Klausel wird die exist()-Methode verwendet, um nur Zeilen zu suchen, die Produktkatalogbeschreibungen enthalten. Das heißt ausschließlich den XML-Code, der das <ProductDescription>-Element enthält.

Dies ist das Ergebnis:

<Product ProductModelID="19"/>
<Product ProductModelID="23"/> 
<Product ProductModelID="25"/> 
<Product ProductModelID="28"><Weight>Varies with size.</Weight></Product>
<Product ProductModelID="34"/>
<Product ProductModelID="35"/>

Die folgende Abfrage ruft dieselben Informationen ab, jedoch nur für solche Produktmodelle, deren Katalogbeschreibung in den Spezifikationen – also im <Specifications>-Element – die Gewichtung enthält – also das <Weight>-Element. In diesem Beispiel wird WITH XLMNAMESPACES zum Deklarieren des pd-Präfixes und seiner Namespacebindung verwendet. Auf diese Weise wird die Bindung nicht sowohl in der query()-Methode als auch in der exist()-Methode beschrieben.

WITH XMLNAMESPACES ('https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription' AS pd)
SELECT CatalogDescription.query('
          <Product  ProductModelID="{ (/pd:ProductDescription/@ProductModelID)[1] }">
                 { 
                      /pd:ProductDescription/pd:Specifications/Weight 
                 } 
          </Product>
') as x
FROM Production.ProductModel
WHERE CatalogDescription.exist('/pd:ProductDescription/pd:Specifications//Weight ') = 1

In der vorherigen Abfrage überprüft die exist()-Methode des xml-Datentyps in der WHERE-Klausel, ob ein <Weight>-Element im <Specifications>-Element vorhanden ist.

B. Suchen nach Produktmodell-IDs für Produktmodelle, deren Katalogbeschreibungen Bilder mit frontalem Blickwinkel und mit geringer Größe enthalten.

Die XML-Produktkatalogbeschreibung enthält die Produktbilder in Form des <Picture>-Elements. Jedes Bild besitzt mehrere Eigenschaften. Dazu gehören der Bildblickwinkel, der durch das <Angle>-Element beschrieben wird, sowie die Bildgröße, die durch das <Size>-Element beschrieben wird.

Für Produktmodelle, deren Katalogbeschreibungen Bilder mit frontalem Blickwinkel und geringer Größe enthalten, konstruiert die Abfrage XML-Code, der die folgende Form aufweist:

< Product ProductModelID="…">
  <Picture>
    <Angle>front</Angle>
    <Size>small</Size>
  </Picture>
</Product>
WITH XMLNAMESPACES ('https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription' AS pd)
SELECT CatalogDescription.query('
   <pd:Product  ProductModelID="{ (/pd:ProductDescription/@ProductModelID)[1] }">
      <Picture>
         {  /pd:ProductDescription/pd:Picture/pd:Angle } 
         {  /pd:ProductDescription/pd:Picture/pd:Size } 
      </Picture>
   </pd:Product>
') as Result
FROM  Production.ProductModel
WHERE CatalogDescription.exist('/pd:ProductDescription/pd:Picture') = 1
AND   CatalogDescription.value('(/pd:ProductDescription/pd:Picture/pd:Angle)[1]', 'varchar(20)')  = 'front'
AND   CatalogDescription.value('(/pd:ProductDescription/pd:Picture/pd:Size)[1]', 'varchar(20)')  = 'small'

Beachten Sie in der vorherigen Abfrage Folgendes:

  • In der WHERE-Klausel wird die exist()-Methode verwendet, um nur Zeilen zu suchen, die Produktkatalogbeschreibungen mit dem <Picture>-Element enthalten.
  • Die WHERE-Klausel verwendet die value()-Methode zweimal, um die Werte der Elemente <Size> und <Angle> zu vergleichen.

Dies ist ein Teilergebnis:

<p1:Product 
  xmlns:p1="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription" 
  ProductModelID="19">
  <Picture>
    <p1:Angle>front</p1:Angle>
    <p1:Size>small</p1:Size>
  </Picture>
</p1:Product>
...

C. Erstellen Sie eine flache Liste der Paare aus Produktmodellname und Feature, wobei jedes Paar im <Features>-Element eingeschlossen ist.

In der Katalogbeschreibung des Produktmodells enthält der XML-Code mehrere Produktfeatures. Alle diese Features sind im <Features>-Element enthalten. Die Abfrage verwendet XML-Erstellung (XQuery) zum Erstellen des erforderlichen XML-Codes. Der Ausdruck in den geschweiften Klammern wird durch das Ergebnis ersetzt.

SELECT CatalogDescription.query('
declare namespace p1="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription";
  for $pd in /p1:ProductDescription,
   $f in $pd/p1:Features/*
  return
   <Feature>
     <ProductModelName> { data($pd/@ProductModelName) } </ProductModelName>
     { $f }
  </Feature>        
') as x
FROM Production.ProductModel
WHERE ProductModelID=19

Beachten Sie in der vorherigen Abfrage Folgendes:

  • $pd/p1:Features/* gibt nur die untergeordneten Elementknoten von <Features> zurück, während $pd/p1:Features/node() alle Knoten zurückgibt. Das schließt Elementknoten, Textknoten, Verarbeitungsanweisungen und Kommentare ein.
  • Die beiden FOR-Schleifen generieren ein kartesisches Produkt, aus dem der Produktname und das individuelle Feature zurückgegeben werden.
  • Der ProductName ist ein Attribut. Die XML-Konstruktion in dieser Abfrage gibt dieses als ein Element zurück.

Dies ist ein Teilergebnis:

<Feature>
 <ProductModelName>Mountain 100</ProductModelName>
 <ProductModelID>19</ProductModelID>
 <p1:Warranty 
   xmlns:p1="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelWarrAndMain">
    <p1:WarrantyPeriod>3 year</p1:WarrantyPeriod>
    <p1:Description>parts and labor</p1:Description>
 </p1:Warranty>
</Feature>
<Feature>
 <ProductModelName>Mountain 100</ProductModelName>
 <ProductModelID>19</ProductModelID>
 <p2:Maintenance xmlns:p2="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelWarrAndMain">
    <p2:NoOfYears>10</p2:NoOfYears>
    <p2:Description>maintenance contact available through your dealer 
           or any AdventureWorks retail store.</p2:Description>
    </p2:Maintenance>
</Feature>
...
...    

D. Aufführen des Produktmodellnamens, der Modell-ID und der in einem <Product>-Element gruppierten Features, ausgehend von der Katalogbeschreibung eines Produktmodells

Unter Verwendung der in der Katalogbeschreibung des Produktmodells gespeicherten Informationen, führt die folgende Abfrage den Produktmodellnamen, die Modell-ID und die in einem <Product>-Element gruppierten Features auf.

SELECT ProductModelID, CatalogDescription.query('
     declare namespace pd="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription";
     <Product>
         <ProductModelName> 
           { data(/pd:ProductDescription/@ProductModelName) } 
         </ProductModelName>
         <ProductModelID> 
           { data(/pd:ProductDescription/@ProductModelID) } 
         </ProductModelID>
         { /pd:ProductDescription/pd:Features/* }
     </Product>        
') as x
FROM Production.ProductModel
WHERE ProductModelID=19

Dies ist ein Teilergebnis:

<Product>
  <ProductModelName>Mountain 100</ProductModelName>
  <ProductModelID>19</ProductModelID>
  <p1:Warranty>... </p1:Warranty>
  <p2:Maintenance>...  </p2:Maintenance>
  <p3:wheel xmlns:p3="https://www.adventure-works.com/schemas/OtherFeatures">High performance wheels.</p3:wheel>
  <p4:saddle xmlns:p4="https://www.adventure-works.com/schemas/OtherFeatures">
    <p5:i xmlns:p5="http://www.w3.org/1999/xhtml">Anatomic design</p5:i> and made from durable leather for a full-day of riding in comfort.</p4:saddle>
  <p6:pedal xmlns:p6="https://www.adventure-works.com/schemas/OtherFeatures">
    <p7:b xmlns:p7="http://www.w3.org/1999/xhtml">Top-of-the-line</p7:b> clipless pedals with adjustable tension.</p6:pedal>
   ...

E. Abrufen der Beschreibungen von Produktmodellfeatures

Die folgende Abfrage konstruiert XML-Code, der ein <Product>-Element enthält, welches die Attribute ProductModelID und ProductModelName sowie die ersten beiden Produktfeatures enthält. Genau genommen sind die ersten beiden Produktfeatures die beiden ersten untergeordneten Elemente des <Features>-Elements. Wenn es darüber hinaus weitere Features gibt, gibt die Abfrage ein leeres <There-is-more/>-Element zurück.

SELECT CatalogDescription.query('
declare namespace pd="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription";
     <Product> 
          { /pd:ProductDescription/@ProductModelID }
          { /pd:ProductDescription/@ProductModelName } 
          {
            for $f in /pd:ProductDescription/pd:Features/*[position()<=2]
            return
            $f 
          }
          {
            if (count(/pd:ProductDescription/pd:Features/*) > 2)
            then <there-is-more/>
            else ()
          } 
     </Product>        
') as Result
FROM Production.ProductModel
WHERE CatalogDescription is not NULL

Beachten Sie in der vorherigen Abfrage Folgendes:

  • Die FOR ... RETURN-Schleifenstruktur ruft die ersten beiden Produktfeatures ab. Die position()-Funktion wird verwendet, um die Position der Elemente in der Sequenz zu finden.

F. Suchen nach Elementnamen aus der Produktkatalogbeschreibung, die mit "ons" enden.

Die folgende Abfrage durchsucht die Katalogbeschreibungen und gibt alle Elemente im <ProductDescription>-Element zurück, deren Namen mit "ons" enden.

SELECT ProductModelID, CatalogDescription.query('
     declare namespace p1="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription";
      for $pd in /p1:ProductDescription/*[substring(local-name(.),string-length(local-name(.))-2,3)="ons"]
      return 
          <Root>
             { $pd }
          </Root>
') as Result
FROM Production.ProductModel
WHERE CatalogDescription is not NULL

Dies ist ein Teilergebnis:

ProductModelID   Result
-----------------------------------------
         19        <Root>       
                     <p1:Specifications xmlns:p1="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription">        
                          ...       
                     </p1:Specifications>       
                   </Root>        

G. Suchen nach zusammenfassenden Beschreibungen, die das Wort "Aerodynamic" enthalten

Die folgende Abfrage ruft die Produktmodelle ab, deren Produktbeschreibung das Wort "Aerodynamic" in der zusammenfassenden Beschreibung enthält:

WITH XMLNAMESPACES ('https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription' AS pd)
SELECT ProductModelID, CatalogDescription.query('
          <Prod >
             { /pd:ProductDescription/@ProductModelID }
             { /pd:ProductDescription/pd:Summary }
          </Prod>
 ') as Result
FROM Production.ProductModel
WHERE CatalogDescription.value('
     contains( string( (/pd:ProductDescription/pd:Summary)[1] ),"Aerodynamic")','bit') = 1

Beachten Sie, dass die SELECT-Abfrage die query()- und value()-Methoden des xml-Datentyps angibt. Deshalb muss die Namespacedeklaration nicht zweimal in zwei verschiedenen Abfrageprologen wiederholt werden, sondern das Präfix pd wird in der Abfrage verwendet und nur einmal mit WITH XMLNAMESPACES definiert.

Beachten Sie in der vorherigen Abfrage Folgendes:

  • Die WHERE-Klausel wird verwendet, um nur solche Zeilen abzurufen, in denen die Katalogbeschreibung das Wort "Aerodynamic" im <Summary>-Element enthält.
  • Die contains()-Funktion wird verwendet, um zu überprüfen, ob das Wort im Text enthalten ist.
  • Die value()-Methode des xml-Datentyps vergleicht den von contains() zurückgegebenen Wert mit 1.

Dies ist das Ergebnis:

ProductModelID Result      
-------------- ------------------------------------------
28     <Prod ProductModelID="28">
        <pd:Summary xmlns:pd="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription">
       <p1:p xmlns:p1="http://www.w3.org/1999/xhtml">
         A TRUE multi-sport bike that offers streamlined riding and a
         revolutionary design. Aerodynamic design lets you ride with the 
         pros, and the gearing will conquer hilly roads.</p1:p>
       </pd:Summary>
      </Prod>  

H. Suchen nach Produktmodellen, deren Katalogbeschreibung keine Produktmodellbilder enthält.

Die folgende Abfrage ruft die ProductModelIDs für Produktmodelle ab, deren Katalogbeschreibung kein <Picture>-Element enthält.

SELECT  ProductModelID
FROM    Production.ProductModel
WHERE   CatalogDescription is not NULL
AND     CatalogDescription.exist('declare namespace p1="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription";
     /p1:ProductDescription/p1:Picture
') = 0

Beachten Sie in der vorherigen Abfrage Folgendes:

  • Wenn die exist()-Methode in der WHERE-Klausel False (0) zurückgibt, wird die Produktmodell-ID zurückgegeben. Ansonsten wird sie nicht zurückgegeben.
  • Weil alle Produktbeschreibungen ein <Picture>-Element enthalten, ist das Resultset in diesem Fall leer.

Siehe auch

Verweis

XQuery-Abfragen unter Einbeziehung von Hierarchien
XQuery-Abfragen, die die Reihenfolge berücksichtigen
Behandlung relationaler Daten mit XQuery-Abfragen
Handhabung von Namespaces in XQuery

Konzepte

Zeichenfolgensuche in XQuery
Hinzufügen von Namespaces mithilfe von WITH XMLNAMESPACES
XML-Datentyp
XML-Datentyp

Andere Ressourcen

XQuery für den xml-Datentyp
Darstellung des xml-Datentyps in der AdventureWorks-Datenbank
XQuery für den xml-Datentyp

Hilfe und Informationen

Informationsquellen für SQL Server 2005