Freigeben über


Allgemeine Einsatzgebiete für XQuery

Gilt für:SQL Server

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

Beispiele

A. Abfragen von Produkten und Gewichten in Katalogbeschreibungen

Die folgende Abfrage gibt die Produktmodell-IDs und (sofern vorhanden) die Gewichtungen aus der Produktkatalogbeschreibung zurück. Die Abfrage erstellt XML in 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 hinsichtlich der vorherigen Abfrage Folgendes:

  • Das namespace-Schlüsselwort im XQuery-Prolog definiert ein Namespacepräfix, das im Abfragetext 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 finden, die Produktkatalogbeschreibungen enthalten. Das heißt, der 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 die Produktmodelle, deren Katalogbeschreibung die Gewichtung, das <Weight> Element, in den Spezifikationen das <Specifications> Element enthält. 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 von Produktmodell-IDs für Produktmodelle, deren Katalogbeschreibungen Bilder mit frontalem Blickwinkel und geringer Größe enthalten

Die Beschreibung des XML-Produktkatalogs enthält die Produktbilder und das <Picture> Element. Jedes Bild besitzt mehrere Eigenschaften. Dazu gehören der Bildwinkel, das <Angle> Element und die Größe, das <Size> Element.

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 hinsichtlich der vorherigen Abfrage Folgendes:

  • In der WHERE-Klausel wird die exist()- Methode verwendet, um nur Zeilen abzurufen, die produktkatalogbeschreibungen mit dem <Picture> -Element enthalten.

  • Die WHERE-Klausel verwendet zweimal die value() -Methode, um die Werte der <Size> Elemente 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 Produktmodellnamen- und Featurepaare, wobei jedes Paar im <Featureelement> eingeschlossen ist.

In der Katalogbeschreibung des Produktmodells enthält der XML-Code mehrere Produktfunktionen. Alle diese Features sind im <Features> -Element enthalten. Die Abfrage verwendet XML-Konstruktion (XQuery), um den erforderlichen XML-Code zu erstellen. 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 hinsichtlich der vorherigen Abfrage Folgendes:

  • $pd/p1:Features/* gibt nur die untergeordneten Elementknoten von <Features>zurück, aber $pd/p1:Features/node() gibt alle Knoten zurück. Das schließt Elementknoten, Textknoten, Verarbeitungsanweisungen und Kommentare ein.

  • Die beiden FOR-Schleifen generieren ein kartesisches Produkt, aus dem der Produktname und die individuelle Funktion zurückgegeben werden.

  • 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: Listen Sie in der Katalogbeschreibung eines Produktmodells den Produktmodellnamen, die Modell-ID und die Features auf, die in einem <Product-Element> gruppiert sind.

Anhand der in der Katalogbeschreibung des Produktmodells gespeicherten Informationen werden in der folgenden Abfrage der Name des Produktmodells, die Modell-ID und die Features aufgelistet, die in einem <Product-Element> gruppiert sind.

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 von Produktmodell-Funktionsbeschreibungen

Die folgende Abfrage erstellt XML, das ein <Product> Element mit ProducModelID, ProductModelName-Attributen und den ersten beiden Produktfeatures enthält. Insbesondere sind die ersten beiden Produktfeatures die ersten beiden untergeordneten Elemente des <Features> Elements. Wenn weitere Features vorhanden sind, wird ein leeres <There-is-more/> Element zurückgegeben.

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 hinsichtlich der vorherigen Abfrage Folgendes:

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

F. Suchen von Elementnamen in der Produktkatalogbeschreibung, die mit "ons" enden

Die folgende Abfrage durchsucht die Katalogbeschreibungen und gibt alle Elemente im <ProductDescription> Element zurück, dessen Name mit "ons" endet.

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 von Zusammenfassungsbeschreibungen mit dem Wort "Aerodynamic"

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 Methoden query() und value() 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 hinsichtlich der vorherigen Abfrage Folgendes:

  • Die WHERE-Klausel wird verwendet, um nur die Zeilen abzurufen, in denen die Katalogbeschreibung das Wort "Aerodynamik" im <Summary> Element enthält.

  • Die contains() -Funktion wird verwendet, um zu ermitteln, 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 ProductModelIDs für Produktmodelle ab, deren Katalogbeschreibungen kein Element enthalten <Picture> .

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 hinsichtlich 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.

  • Da alle Produktbeschreibungen ein <Picture> Element enthalten, ist das Resultset in diesem Fall leer.

Weitere Informationen

XQuery-Abfragen unter Einbeziehung von Hierarchien
XQuery-Abfragen, die die Reihenfolge berücksichtigen
Behandlung relationaler Daten mit XQuery-Abfragen
Zeichenfolgensuche in XQuery
Handhabung von Namespaces in XQuery
Hinzufügen von Namespaces zu Abfragen mit WITH XMLNAMESPACES
XML-Daten (SQL Server)
XQuery-Sprachreferenz (SQL Server)