Выражения условий (XQuery)
Язык XQuery поддерживает следующий условный оператор if-then-else:
if (<expression1>)
then
<expression2>
else
<expression3>
В зависимости от действительного логического значения вычисляется выражение expression1, expression2 или expression3, например следующим образом.
Если выражение условия expression1 соответствует пустой последовательности, результат имеет значение False.
Если выражение expression1 соответствует простому логическому значению, оно и является результатом выражения.
Если выражение expression1 соответствует последовательности из одного или более узлов, результатом выражения является значение True.
В остальных случаях возникает статическая ошибка.
Имейте в виду следующее.
Выражение условия должно быть заключено в скобки.
Выражение else обязательно. Если оно не требуется, можно возвратить « ( ) », как показано в примерах, приведенных в этом подразделе.
Например, следующий запрос выполняется для переменной типа xml. В условии оператора if, входящего в выражение XQuery, при помощи функции расширения sql:variable() проверяется значение 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>
Следующий запрос возвращает элемент <Location> с атрибутом LocationID, если для цеха не задано рабочее время.
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