Partager via


Cas d’usage généraux de XQuery

S'applique à :SQL Server

Cet article fournit des exemples généraux d’utilisation de XQuery.

Exemples

R. Interrogation des descriptions d'un catalogue pour rechercher des produits et des poids

La requête suivante renvoie les ID de modèle de produit et les poids, le cas échéant, de la description du catalogue de produits. La requête construit du code XML se présentant sous la forme suivante :

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

Voici la requête :

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;

Notez les considérations suivantes de la requête précédente :

  • Le namespace mot clé du prolog XQuery définit un préfixe d’espace de noms utilisé dans le corps de la requête.

  • Le corps de la requête construit le code XML requis.

  • Dans la WHERE clause, la exist() méthode est utilisée pour rechercher uniquement les lignes qui contiennent des descriptions de catalogue de produits. Autrement dit, le code XML qui contient l’élément <ProductDescription> .

Voici le résultat :

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

La requête suivante récupère les mêmes informations, mais uniquement pour les modèles de produit dont la description du catalogue inclut le poids, l’élément <Weight> , dans les spécifications, l’élément <Specifications> . Cet exemple utilise WITH XMLNAMESPACES pour déclarer le pd préfixe et sa liaison d’espace de noms. De cette façon, la liaison n’est pas décrite à la fois dans la query() méthode et dans la exist() méthode.

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;

Dans la requête précédente, la exist() méthode du type de données xml dans la WHERE clause vérifie s’il existe un <Weight> élément dans l’élément <Specifications> .

B. Recherche des ID des modèles de produit dont les descriptions englobent des illustrations de face et de petite taille

La description du catalogue de produits XML inclut les images de produit, l’élément <Picture> . Chaque image a plusieurs propriétés, notamment l’angle de l’image (l’élément <Angle> ) et la taille (l’élément <Size> ).

Pour les modèles de produit dont les descriptions du catalogue englobent des illustrations de face et de petite taille, la requête construit le code XML sous la forme suivante :

< 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'

Notez les considérations suivantes de la requête précédente :

  • Dans la WHERE clause, la exist() méthode est utilisée pour récupérer uniquement les lignes qui ont des descriptions de catalogue de produits avec l’élément <Picture> .

  • La WHERE clause utilise la value() méthode deux fois pour comparer les valeurs des éléments et <Angle> des <Size> éléments.

Voici un résultat partiel :

<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. Créer une liste plate du nom du modèle de produit et des paires de fonctionnalités, avec chaque paire placée entre l’élément <Features>

Dans la description du catalogue de produits, le code XML englobe plusieurs caractéristiques du produit. Toutes ces fonctionnalités sont incluses dans l’élément <Features> . La requête utilise la construction XML (XQuery) pour construire le code XML requis. L'expression entre accolades est remplacée par le résultat.

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;

Notez les considérations suivantes de la requête précédente :

  • $pd/p1:Features/* retourne uniquement les enfants de nœud d’élément de <Features>, mais $pd/p1:Features/node() retourne tous les nœuds. notamment les nœuds d'élément et de texte, les instructions de traitement et les commentaires.

  • Les deux FOR boucles génèrent un produit cartésien à partir duquel le nom du produit et la fonctionnalité individuelle sont retournés.

  • Il ProductName s’agit d’un attribut. La construction XML de cette requête le renvoie sous forme d'élément.

Voici un résultat partiel :

<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. Dans la description du catalogue d’un modèle de produit, répertoriez le nom du modèle de produit, l’ID de modèle et les fonctionnalités regroupées à l’intérieur d’un <élément Product>

À l’aide des informations stockées dans la description du catalogue du modèle de produit, la requête suivante répertorie le nom du modèle de produit, l’ID de modèle et les fonctionnalités regroupées à l’intérieur d’un <Product> élément.

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;

Voici un résultat partiel :

<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. Récupération de la description des caractéristiques d'un modèle de produit

La requête suivante construit du code XML qui inclut un <Product> élément qui a ProductModelID, ProductModelName des attributs et les deux premières fonctionnalités de produit. Plus précisément, les deux premières fonctionnalités de produit sont les deux premiers éléments enfants de l’élément <Features> . S’il existe d’autres fonctionnalités, elle retourne un élément vide <There-is-more/> .

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;

Notez les considérations suivantes de la requête précédente :

  • La FOR structure de boucle ... RETURN récupère les deux premières fonctionnalités du produit. La position() fonction est utilisée pour rechercher la position des éléments dans la séquence.

F. Rechercher des noms d’éléments à partir de la description du catalogue de produits qui se terminent par ons

La requête suivante recherche les descriptions du catalogue et retourne tous les éléments de l’élément dont le <ProductDescription> nom se termine par 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;

Voici un résultat partiel :

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

G. Recherche des descriptions résumées qui contiennent le mot « Aerodynamic »

La requête suivante récupère les modèles de produit dont les descriptions du catalogue contiennent le mot « Aerodynamic » dans la description résumée :

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;

La SELECT requête spécifie query() et value() les méthodes du type de données xml . Par conséquent, au lieu de répéter la déclaration d’espaces de noms deux fois dans deux prologs de requête de différence, le préfixe pd est utilisé dans la requête et n’est défini qu’une seule fois à l’aide WITH XMLNAMESPACESde .

Notez les considérations suivantes de la requête précédente :

  • La WHERE clause est utilisée pour récupérer uniquement les lignes où la description du catalogue contient le mot « Aérodynamique » dans l’élément <Summary> .

  • La contains() fonction est utilisée pour voir si le mot est inclus dans le texte.

  • La value() méthode du type de données xml compare la valeur retournée par contains() 1.

Voici le résultat :

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. Rechercher des modèles de produit dont les descriptions de catalogue n’incluent pas d’images de modèle de produit

La requête suivante récupère les ProductModelIDs pour les modèles de produit dont les descriptions de catalogue n’incluent pas d’élément <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;

Notez les considérations suivantes de la requête précédente :

  • Si la exist() méthode dans la WHERE clause retourne False (0), l’ID de modèle de produit est retourné. Sinon, elle n’est pas retournée.

  • Étant donné que toutes les descriptions de produit incluent un <Picture> élément, le jeu de résultats est vide dans ce cas.