Freigeben über


Allgemeine XQuery-Anwendungsfälle

Gilt für:SQL Server

Dieser Artikel enthält allgemeine Beispiele für die Verwendung von XQuery.

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>

Hier ist die Abfrage:

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 die folgenden Überlegungen aus der vorherigen Abfrage:

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

Das Ergebnis lautet wie folgt:

<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 die gleichen Informationen ab, aber nur für diese Produktmodelle, deren Katalogbeschreibung die Gewichtung, das <Weight> Element in den Spezifikationen, das <Specifications> Element enthält. In diesem Beispiel wird WITH XMLNAMESPACES das pd Präfix und die Namespacebindung deklariert. 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 XML-Produktkatalogbeschreibung enthält die Produktbilder, das <Picture> Element. Jedes Bild verfügt über mehrere Eigenschaften, einschließlich des Bildwinkels (element <Angle> ) und der Größe (des <Size> Elements).

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 die folgenden Überlegungen aus der vorherigen Abfrage:

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

  • Die WHERE Klausel verwendet die value() Methode zweimal, um die Werte der <Size> Elemente zu <Angle> vergleichen.

Hier 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 Einer flachen Liste der Produktmodellnamen und Featurepaare, wobei jedes Paar in das <Features-Element> 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 die 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 die folgenden Überlegungen aus der vorherigen Abfrage:

  • $pd/p1:Features/* gibt nur die untergeordneten Elemente des Elementknotens zurück <Features>, gibt jedoch $pd/p1:Features/node() 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 das einzelne Feature zurückgegeben werden.

  • Dies ProductName ist ein Attribut. Die XML-Konstruktion in dieser Abfrage gibt dieses als ein Element zurück.

Hier 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 <Produktelement> gruppiert sind.

Mithilfe der informationen, die in der Katalogbeschreibung des Produktmodells gespeichert sind, werden in der folgenden Abfrage der Name des Produktmodells, die Modell-ID und die Features aufgelistet, die innerhalb eines <Product> Elements 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;

Hier 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, die ein <Product> Element mit ProductModelIDProductModelName 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 die folgenden Überlegungen aus der vorherigen Abfrage:

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

F. Suchen von Elementnamen aus der Produktkatalogbeschreibung, die mit ons

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

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;

Hier 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;

Die SELECT Abfrage gibt und value() Methoden des XML-Datentyps anquery(). Daher wird das Präfix pd in der Abfrage verwendet, anstatt die Namespaces-Deklaration zweimal in zwei unterschiedlichen Abfrageprologs zu wiederholen und wird nur einmal mithilfe der Verwendung WITH XMLNAMESPACESdefiniert.

Beachten Sie die folgenden Überlegungen aus der vorherigen Abfrage:

  • 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 festzustellen, ob das Wort im Text enthalten ist.

  • Die value() Methode des XML-Datentyps vergleicht den von 1 zurückgegebenen contains() Wert.

Das Ergebnis lautet wie folgt:

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 von Produktmodellen, deren Katalogbeschreibungen keine Produktmodellbilder enthalten

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 die folgenden Überlegungen aus der vorherigen Abfrage:

  • Wenn die exist() Methode in der WHERE Klausel "False" (0) zurückgibt, wird die Produktmodell-ID zurückgegeben. Andernfalls wird sie nicht zurückgegeben.

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