Выражения сравнения (XQuery)
Применимо к:SQL Server
Язык XQuery предоставляет следующие типы операторов сравнения:
общие операторы сравнения;
операторы сравнения значений;
операторы сравнения узлов;
операторы сравнения порядка узлов.
Общие операторы сравнения
Общие операторы сравнения могут быть использованы для сравнения атомарных значений, последовательностей или любого их сочетания.
Общие операторы определены в представленной ниже таблице.
Operator | Описание: |
---|---|
= | Equal |
!= | Not equal |
< | Меньше |
> | Больше |
<= | Меньше или равно |
>= | Больше или равно |
При сравнении двух последовательностей с помощью общих операторов сравнения, когда во второй последовательности существует значение, при сравнении которого со значением в первой последовательности возвращается результат True, то итоговым результатом будет значение True. В противном случае общим результатом будет значение False. Например: выражение (1, 2, 3) = (3, 4) имеет значение True, потому что значение 3 встречается в обеих последовательностях.
declare @x xml
set @x=''
select @x.query('(1,2,3) = (3,4)')
Сравнение предполагает, что значения относятся к сравниваемым типам. Точнее, выполняется их статическая проверка. При сравнении чисел может возникать продвижение числового типа. Например: если десятичное значение 10 сравнивается со значением 1e1 типа double, десятичное значение преобразуется в тип double. Обратите внимание, что эти результаты могут быть неточными, так как сравнения типа double точными быть не могут.
Если одно из значений является нетипизированным, оно приводится к типу другого значения. В следующем примере значение 7 рассматривается как целое. Перед сравнением нетипизированное значение /a[1] преобразовывается в целое. Сравнение целых чисел возвращает значение True.
declare @x xml
set @x='<a>6</a>'
select @x.query('/a[1] < 7')
И наоборот: если нетипизированное значение сравнивается со строкой или другим нетипизированным значением, оно приводится к значению xs:string. В следующем запросе строка «6» сравнивается со строкой «17». Этот запрос возвращает значение False, так как выполняется сравнение строк.
declare @x xml
set @x='<a>6</a>'
select @x.query('/a[1] < "17"')
Следующий запрос возвращает небольшие изображения модели продуктов из каталога продуктов, представленного в образце базы данных AdventureWorks. Запрос сравнивает последовательность атомарных значений, возвращаемых PD:ProductDescription/PD:Picture/PD:Size
с одноэлементной последовательностью «small». Если сравнение равно True, он возвращает <элемент Picture> .
WITH XMLNAMESPACES ('https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription' AS PD)
SELECT CatalogDescription.query('
for $P in /PD:ProductDescription/PD:Picture[PD:Size = "small"]
return $P') as Result
FROM Production.ProductModel
WHERE ProductModelID=19
Следующий запрос сравнивает последовательность телефонных номеров в <нумеровых> элементах со строковым литералом "112-111-1111". Запрос сравнивает последовательность элементов телефонных номеров в столбце AdditionalContactInfo, чтобы определить существует ли в документе конкретный телефонный номер для конкретного заказчика.
WITH XMLNAMESPACES (
'https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactTypes' AS act,
'https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactInfo' AS aci)
SELECT AdditionalContactInfo.value('
/aci:AdditionalContactInfo//act:telephoneNumber/act:number = "112-111-1111"', 'nvarchar(10)') as Result
FROM Person.Contact
WHERE ContactID=1
Запрос возвращает значение True. Это означает, что номер в документе существует. Следующий запрос является незначительной модификацией предыдущего. В нем значения телефонных номеров, получаемых из документа, сравниваются с последовательностью из двух значений телефонных номеров. Если сравнение равно True, <возвращается элемент number> .
WITH XMLNAMESPACES (
'https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactTypes' AS act,
'https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactInfo' AS aci)
SELECT AdditionalContactInfo.query('
if (/aci:AdditionalContactInfo//act:telephoneNumber/act:number = ("222-222-2222","112-111-1111"))
then
/aci:AdditionalContactInfo//act:telephoneNumber/act:number
else
()') as Result
FROM Person.Contact
WHERE ContactID=1
Результат:
\<act:number
xmlns:act="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactTypes">
111-111-1111
\</act:number>
\<act:number
xmlns:act="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactTypes">
112-111-1111
\</act:number>
Операторы сравнения значений
Операторы сравнения значений используются для сравнения атомарных значений. Обратите внимание, что вместо операторов сравнения значений в запросах можно использовать общие операторы сравнения.
Операторы сравнения значений определены в следующей таблице.
Operator | Описание: |
---|---|
eq | Равно |
ne | Not equal |
lt | Меньше |
gt | Больше |
le | Меньше или равно |
ge | Больше или равно |
Если согласно выбранному оператору два значения сравнивают одно и тоже, выражение возвратит True. В противном случае будет возвращено False. Если какое-либо из значений является пустой последовательностью, результатом выражения будет False.
Эти операторы работают только для одноэлементных атомарных значений. Таким образом, нельзя указать последовательность в качестве одного из операндов.
Например, следующий запрос извлекает <элементы Picture> для модели продукта, где размер рисунка имеет значение "small:
SELECT CatalogDescription.query('
declare namespace PD="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription";
for $P in /PD:ProductDescription/PD:Picture[PD:Size eq "small"]
return
$P
') as Result
FROM Production.ProductModel
WHERE ProductModelID=19
Обратите внимание на следующие данные из предыдущего запроса:
Инструкция
declare namespace
определяет префикс пространства имен, который затем используется в запросе.<Значение элемента Size> сравнивается с указанным атомарным значением small.
Обратите внимание, что поскольку операторы значений работают только с атомарными значениями, функция data() неявно используется для получения значения узла. То есть функция
data($P/PD:Size) eq "small"
выдает тот же результат.
Результат:
\<PD:Picture
xmlns:PD="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription">
\<PD:Angle>front\</PD:Angle>
\<PD:Size>small\</PD:Size>
\<PD:ProductPhotoID>31\</PD:ProductPhotoID>
\</PD:Picture>
Обратите внимание, что правила продвижения типа для сравнений значений такие же, как и для общих сравнений. Кроме того, SQL Server использует те же правила приведения для нетипизированных значений во время сравнения значений, которые используются во время общих сравнений. И напротив, по правилам в спецификации XQuery при выполнении сравнений значений нетипизированное значение всегда приводится к значению xs:string.
Операторы сравнения узлов
Оператор сравнения узлов применяется только к типам узлов. Возвращаемый им результат указывает, представляют ли два переданных как операнды узла в исходном документе один узел. Этот оператор возвращает значение True, если два операнда являются одним узлом. В противном случае возвращается значение False.
Следующий запрос проверяет, является ли 10-й участок цеха первым в производственном процессе определенной модели продукта.
WITH XMLNAMESPACES ('https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelManuInstructions' AS AWMI)
SELECT ProductModelID, Instructions.query('
if ( (//AWMI:root/AWMI:Location[@LocationID=10])[1]
is
(//AWMI:root/AWMI:Location[1])[1] )
then
<Result>equal</Result>
else
<Result>Not-equal</Result>
') as Result
FROM Production.ProductModel
WHERE ProductModelID=7
Результат:
ProductModelID Result
-------------- --------------------------
7 <Result>equal</Result>
Операторы сравнения порядка узлов
Операторы сравнения порядка узлов сравнивают пары узлов, исходя из их позиций в документе.
На основе порядка документа выполняются следующие сравнения:
<<
: предшествует операнду 1 операнду 2 в порядке документа.>>
: следует ли операнду 1 операнду 2 в порядке документа.
Следующий запрос возвращает значение True, если в описании каталога продуктов элемент <"Гарантия"> отображается перед <элементом "Обслуживание> " в заказе документа для определенного продукта.
WITH XMLNAMESPACES (
'https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription' AS PD,
'https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelWarrAndMain' AS WM)
SELECT CatalogDescription.value('
(/PD:ProductDescription/PD:Features/WM:Warranty)[1] <<
(/PD:ProductDescription/PD:Features/WM:Maintenance)[1]', 'nvarchar(10)') as Result
FROM Production.ProductModel
where ProductModelID=19
Обратите внимание на следующие данные из предыдущего запроса:
Метод value() типа данных XMLиспользуется в запросе.
Логический результат запроса преобразуется в nvarchar(10) и возвращается.
Запрос возвращает значение True.