Freigeben über


Bedingte Ausdrücke (XQuery)

XQuery unterstützt die folgende if-then-else-Anweisung:

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

Abhängig vom effektiven booleschen Wert von expression1 wird entweder expression2 oder expression3 ausgewertet. Beispiel:

  • Wenn der Testausdruck expression1 eine leere Sequenz ergibt, ist das Ergebnis "False".

  • Wenn der Testausdruck expression1 einen einfachen booleschen Wert ergibt, gilt dieser Wert als Ergebnis des Ausdrucks.

  • Wenn der Testausdruck expression1 eine Sequenz aus einem oder mehreren Knoten ergibt, ist das Ergebnis des Ausdrucks "True".

  • Anderenfalls wird ein statischer Fehler ausgegeben.

Beachten Sie dabei außerdem Folgendes:

  • Der Testausdruck muss in Klammern stehen.

  • Der else-Ausdruck ist erforderlich. Falls Sie ihn nicht benötigen, können Sie " ( ) " zurückgeben, wie dies in den Beispielen der Fall ist.

Die folgende Abfrage erfolgt beispielsweise in Bezug auf die xml-Typvariable. Die if-Bedingung testet den Wert der SQL-Variablen (@v) des XQuery-Ausdrucks anhand der Erweiterungsfunktion sql:variable() function. Wenn der Variablenwert "FirstName" ist, wird das <FirstName>-Element zurückgegeben. Anderenfalls wird das <LastName>-Element zurückgegeben.

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

Dies ist das Ergebnis:

<FirstName>fname</FirstName>

Die folgende Abfrage ruft die beiden ersten Funktionsbeschreibungen der Produktkatalogbeschreibung eines bestimmten Produktmodells ab. Wenn mehr Funktionen im Dokument enthalten sind, wird ein leeres <there-is-more>-Element hinzugefügt.

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

In der obigen Abfrage prüft die Bedingung des if-Ausdrucks, ob in <Features> mehr als zwei untergeordnete Elemente vorhanden sind. Wenn dies der Fall ist, wird als Ergebnis ein <there-is-more/>-Element zurückgegeben.

Dies ist das Ergebnis:

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

In der folgenden Abfrage wird ein <Location>-Element mit einem LocationID-Attribut zurückgegeben, wenn der Arbeitsplatzstandort keine Rüstzeiten angibt.

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

Dies ist das Ergebnis:

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

Diese Abfrage kann, wie im folgenden Beispiel, ohne if-Klausel geschrieben werden:

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

Siehe auch

Konzepte