Expressions conditionnelles (XQuery)

XQuery prend en charge l'instruction if-then-else conditionnelle suivante :

if (<expression1>)
then
  <expression2>
else
  <expression3>

Suivant la valeur booléenne effective de expression1, expression2 ou expression3 est évaluée. Exemple :

  • Si l'expression de test, expression1, aboutit à une séquence vide, le résultat est False.

  • Si l'expression de test, expression1, aboutit à une valeur booléenne simple, cette valeur est le résultat de l'expression.

  • Si l'expression de test, expression1, aboutit à une séquence d'un ou plusieurs nœuds, le résultat de l'expression est True.

  • Sinon, une erreur statique est déclenchée.

En outre, notez les points suivants :

  • L'expression de test doit figurer entre parenthèses.

  • L'expression else est requise. Si vous n'en avez pas besoin, vous pouvez renvoyer « ( ) », comme le montrent les exemples de cette rubrique.

Par exemple, la requête suivante est spécifiée par rapport à la variable de type xml. La condition if teste la valeur de la variable SQL (@v) dans l'expression XQuery à l'aide de la fonction d'extension sql:variable(). Si la valeur de la variable est « FirstName », elle renvoie l'élément <FirstName>. Sinon, elle renvoie l'élément <LastName>.

declare @x xml
declare @v varchar(20)
set @v='FirstName'
set @x='
<ROOT rootID="2">
  <FirstName>fname</FirstName>
  <LastName>lname</LastName>
</ROOT>'
SELECT @x.query('
if ( sql:variable("@v")="FirstName" ) then
  /ROOT/FirstName
 else
   /ROOT/LastName
')

Voici le résultat obtenu :

<FirstName>fname</FirstName>

La requête suivante extrait les deux premières descriptions de fonctionnalités de la description de catalogue de produit d'un modèle de produit spécifique. Si le document comporte davantage de fonctionnalités, elle ajoute un élément <there-is-more> avec un contenu vide.

SELECT CatalogDescription.query('
     declare namespace p1="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription";
     <Product> 
          { /p1:ProductDescription/@ProductModelID }
          { /p1:ProductDescription/@ProductModelName } 
          {
            for $f in /p1:ProductDescription/p1:Features/*[position()<=2]
            return
            $f 
          }
          {
            if (count(/p1:ProductDescription/p1:Features/*) > 2)
            then <there-is-more/>
            else ()
          } 
     </Product>        
') as x
FROM Production.ProductModel
WHERE ProductModelID = 19

Dans la requête précédente, la condition de l'expression if vérifie si <Features> contient plus de deux éléments enfants. Si tel est le cas, elle renvoie l'élément <there-is-more/> dans le résultat.

Voici le résultat obtenu :

<Product ProductModelID="19" ProductModelName="Mountain 100">
  <p1:Warranty xmlns:p1="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelWarrAndMain">
    <p1:WarrantyPeriod>3 years</p1:WarrantyPeriod>
    <p1:Description>parts and labor</p1:Description>
  </p1:Warranty>
  <p2:Maintenance xmlns:p2="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelWarrAndMain">
    <p2:NoOfYears>10 years</p2:NoOfYears>
    <p2:Description>maintenance contract available through your dealer or any Adventure Works Cycles retail store.</p2:Description>
  </p2:Maintenance>
  <there-is-more />
</Product>

Dans la requête suivante, un élément <Location> doté d'un attribut LocationID est renvoyé si le site de production ne spécifie pas les heures de préparation (@SetupHours).

SELECT Instructions.query('
     declare namespace AWMI="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelManuInstructions";
        for $WC in //AWMI:root/AWMI:Location
        return
        if ( $WC[not(@SetupHours)] )
        then
          <WorkCenterLocation>
             { $WC/@LocationID } 
          </WorkCenterLocation>
         else
           ()
') as Result
FROM Production.ProductModel
where ProductModelID=7

Voici le résultat obtenu :

<WorkCenterLocation LocationID="30" />
<WorkCenterLocation LocationID="45" />
<WorkCenterLocation LocationID="60" />

Cette requête peut être écrite sans la clause if, comme le montre l'exemple suivant :

SELECT Instructions.query('
     declare namespace AWMI="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelManuInstructions";
for $WC in //AWMI:root/AWMI:Location[not(@SetupHours)] 
        return
          <Location>
             { $WC/@LocationID } 
          </Location>
') as Result
FROM Production.ProductModel
where ProductModelID=7

Voir aussi

Concepts