Cas d'emploi généraux des requêtes XQuery

S’applique à :SQL Server

Cette rubrique donne des exemples généraux d'emploi de requêtes 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 points suivants dans la requête précédente :

  • Le mot clé d’espace de noms dans le 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 clause WHERE, la méthode exist() 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 obtenu :

<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 produits dont la description du catalogue inclut le poids, l’élément, dans les spécifications, l’élément<Specifications>.<Weight> Cet exemple utilise WITH XMLNAMESPACES pour déclarer le préfixe pd et sa liaison d'espace de noms. De cette façon, la liaison n’est pas décrite à la fois dans la méthode query() et dans la méthode exist().

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 méthode exist() du type de données xml dans la clause WHERE 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 illustration a plusieurs propriétés dont Il s’agit notamment de l’angle de l’image, de l’élément et de la taille de l’élément<Size>.<Angle>

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 points suivants dans la requête précédente :

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

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

Voici un extrait du résultat :

<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, chaque paire étant placée dans 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 points suivants dans 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 boucles FOR génèrent un produit cartésien à partir duquel le nom du produit et ses caractéristiques sont renvoyés.

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

Voici un extrait du résultat :

<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 <élément Product> .

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 extrait du résultat :

<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 des attributs ProducModelID, ProductModelName et les deux premières fonctionnalités de produit. Plus précisément, les deux premières fonctionnalités du produit sont les deux premiers éléments enfants de l’élément <Features> . S’il existe d’autres fonctionnalités, il 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 points suivants dans la requête précédente :

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

F. Recherche de noms d'élément se terminant par « ons », d'après les descriptions du catalogue de produits

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 extrait du résultat :

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  

Notez que la requête SELECT spécifie les méthodes query() et value() du type de données xml . Par conséquent, au lieu de répéter deux fois la déclaration des espaces de noms dans deux prologues de requête différents, le préfixe pd est utilisé dans la requête, puis défini une seule fois à l'aide de WITH XMLNAMESPACES.

Notez les points suivants dans la requête précédente :

  • La clause WHERE 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 fonction contains() est utilisée pour voir si le mot est inclus dans le texte.

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

Voici le résultat obtenu :

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. Recherche de modèles de produit dont les descriptions du catalogue ne s'accompagnent pas d'illustrations

La requête suivante récupère les ProductModelID 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 points suivants dans la requête précédente :

  • Si la méthode exist() dans la clause WHERE retourne False (0), l’ID de modèle de produit est retourné. Dans le cas contraire, aucune donnée n'est renvoyée.

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

Voir aussi

Requêtes XQuery impliquant une hiérarchie
Requêtes XQuery impliquant un ordre
Requêtes XQuery pour la gestion des données relationnelles
Recherche de chaînes dans XQuery
Gestion des espaces de noms dans XQuery
Ajouter des espaces de noms aux requêtes avec WITH XMLNAMESPACES
Données XML (SQL Server)
Références relatives au langage Xquery (SQL Server)