条件表达式 (XQuery)

XQuery 支持以下的 if-then-else 条件语句:

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

根据 expression1 的有效的布尔值,选择计算 expression2 或 expression3。例如:

  • 如果测试表达式 expression1 结果为空序列,则结果为 False。

  • 如果测试表达式 expression1 结果为简单布尔值,则此值即为该表达式的结果。

  • 如果测试表达式 expression1 产生一个或多个节点的序列,则该表达式的结果为 True。

  • 否则,将引发静态错误。

另请注意下列事项:

  • 测试表达式必须用括号括起来。

  • else 表达式是必需的。如果不需要该表达式,可以返回“( )”,如本主题中的示例所示。

例如,对 xml 类型变量指定以下查询。if 条件通过使用 sql:variable() function 扩展函数测试 XQuery 表达式中的 SQL 变量 (@v) 的值。如果变量值为“FirstName”,则返回 <FirstName> 元素。否则,返回 <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
')

结果如下:

<FirstName>fname</FirstName>

以下查询从特定产品样式的产品目录说明中检索前两个功能说明。如果文档有多个功能,则添加空内容的 <there-is-more> 元素。

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

在上一个查询中,if 表达式中的条件将检查 <Features> 是否有超过两个的子元素。如果有,则在结果中返回 <there-is-more/> 元素。

结果如下:

<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 AdventureWorks retail store.</p2:Description>
  </p2:Maintenance>
  <there-is-more />
</Product>

在以下查询中,如果生产车间不指定安装时间,则返回具有 LocationID 属性的 <Location> 元素。

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

结果如下:

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

可以编写此查询(没有 if 子句),如以下示例所示:

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

请参阅

概念