Freigeben über


Allgemeine Einsatzgebiete für XQuery

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 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. Dies bedeutet, dass das <ProductDescription>-Element im XML enthalten ist.

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"/>

Mit der folgenden Abfrage werden die gleichen Informationen abgerufen, jedoch nur für die Produktmodelle, deren Katalogbeschreibung das Gewicht, das <Weight>-Element, in den Spezifikationen, im <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 wird mit der exist()-Methode des xml-Datentyps in der WHERE-Klausel überprüft, 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 Produktbilder sind im XML der Produktkatalogbeschreibung im <Picture>-Element enthalten. 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 werden mit der exist()-Methode nur die Zeilen abgerufen, deren Produktkatalogbeschreibungen das <Picture>-Element enthalten.

  • Die value()-Methode wird von der WHERE-Klausel zweimal ausgeführt, um die Werte des <Size>-Elements und des <Angle>-Elements 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 einer flachen Liste mit Paaren aus Produktmodellname und -funktion, die jeweils in ein <Features>-Element eingeschlossen sind

In der Katalogbeschreibung des Produktmodells enthält der XML-Code mehrere Produktfunktionen. All diese Funktionen werden in das <Features>-Element eingeschlossen. 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 Elemente des <Features>-Knotens zurück; $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.

  • 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.Auflisten von Produktmodellname, -ID und -funktionen in einem <Product>-Element anhand der Katalogbeschreibung des Produktmodells

Die folgende Abfrage listet den Produktmodellnamen sowie die zugehörige ID und die entsprechenden Funktionen anhand der in der Katalogbeschreibung des Produktmodells gespeicherten Informationen in einem <Product>-Element 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 das 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 mit einem <Product>-Element, das das ProducModelID-Attribut, das ProductModelName-Attribut sowie die ersten beiden Produktfunktionen enthält. Genau genommen sind die ersten beiden Produktfunktionen die beiden ersten untergeordneten Elemente des <Features>-Elements. Wenn es darüber hinaus weitere Funktionen 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 folgendes hinsichtlich der vorherigen Abfrage:

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

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

  • Mit der WHERE-Klausel werden nur die Zeilen abgerufen, für die 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 ProductModelIDs für Produktmodelle ab, deren Katalogbeschreibungen kein <Picture>-Element enthalten.

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.

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 zu Abfragen mit WITH XMLNAMESPACES

XML-Daten (SQL Server)

Andere Ressourcen

XQuery-Sprachreferenz (SQL Server)