Метод exist() (тип данных xml)
Возвращает значение типа bit, которое представляет одно из следующих состояний:
1, означающее True, если выражение на языке XQuery при запросе возвращает непустой результат, то есть возвращается как минимум один узел XML.
0, означающее False при возвращении пустого результата.
Значение NULL, если экземпляр типа xml, к которому был выполнен запрос, содержит значение NULL.
Примечание |
---|
Метод exist() возвращает 1 для выражения XQuery, которое возвращает непустой результат. Если указать функции true() или false() внутри метода exist(), метод exist() вернет 1, так как функции true() и false() возвращают логические значения True и False соответственно. То есть они возвращают непустой результат. Поэтому метод exist() вернет 1 (True), как показано в следующем примере: |
declare @x xml
set @x=''
select @x.exist('true()')
Синтаксис
exist (XQuery)
Аргументы
- XQuery
Выражение на языке XQuery, строковый литерал.
Примеры
Следующий пример демонстрирует указание метода exist().
Пример. Указание метода exist() по отношению к переменной типа xml
В следующем примере @x является переменной типа xml (нетипизированный xml), а @f является переменной целочисленного типа, которая хранит значение, возвращенное методом exist(). Метод exist() возвращает значение True (1), если значение даты, хранимое в экземпляре XML, равно 2002-01-01.
declare @x xml
declare @f bit
set @x = '<root Somedate = "2002-01-01Z"/>'
set @f = @x.exist('/root[(@Somedate cast as xs:date?) eq xs:date("2002-01-01Z")]')
select @f
В сравнении дат в методе exist() обратите внимание на следующее:
Код cast as xs:date? используется для приведения значения к типу xs:date с целью сравнения.
Значение атрибута @Somedate является нетипизированным. При сравнении это значение неявно приводится к типу правой части выражения сравнения, а именно к типу xs:date.
Вместо выражения cast as xs:date() можно использовать функцию-конструктор xs:date(). Дополнительные сведения см. в разделе Функции-конструкторы (XQuery).
Следующий пример похож на предыдущий, отличаясь только наличием элемента <Somedate>.
DECLARE @x xml
DECLARE @f bit
SET @x = '<Somedate>2002-01-01Z</Somedate>'
SET @f = @x.exist('/Somedate[(text()[1] cast as xs:date ?) = xs:date("2002-01-01Z") ]')
SELECT @f
В предыдущем запросе обратите внимание на следующее:
- Метод text() возвращает текстовый узел, содержащий нетипизированное значение 2002-01-01. (XQuery имеет тип xdt:untypedAtomic.) Необходимо явно привести это типизированное значение от x к xsd:date, поскольку неявное приведение в данном случае не поддерживается.
Пример. Указание метода exist() по отношению к типизированной переменной xml
В следующем примере иллюстрируется применение метода exist() к переменной типа xml. Это типизированная переменная XML, поскольку она указывает имя схемы коллекции пространства имен, ManuInstructionsSchemaCollection.
В этом примере переменной вначале присваивается документ с инструкциями по производству, а затем используется метод exist(), чтобы выяснить, содержится ли в документе элемент <Location>, атрибут которого LocationID имеет значение 50.
Метод exist(), примененный к переменной @x, возвращает значение 1 (True), если документ с инструкциями по производству содержит элемент <Location> с атрибутом LocationID=50. В противном случае метод возвращает значение 0 (False).
DECLARE @x xml (Production.ManuInstructionsSchemaCollection)
SELECT @x=Instructions
FROM Production.ProductModel
WHERE ProductModelID=67
--SELECT @x
DECLARE @f int
SET @f = @x.exist(' declare namespace AWMI="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelManuInstructions";
/AWMI:root/AWMI:Location[@LocationID=50]
')
SELECT @f
Пример. Указание метода exist() по отношению к столбцу типа xml
В следующем запросе производится получение идентификаторов моделей продукции, описания которых в каталоге не содержат спецификаций, то есть элемента <Specifications>:
SELECT ProductModelID, CatalogDescription.query('
declare namespace pd="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription";
<Product
ProductModelID= "{ sql:column("ProductModelID") }"
/>
') AS Result
FROM Production.ProductModel
WHERE CatalogDescription.exist('
declare namespace pd="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription";
/pd:ProductDescription[not(pd:Specifications)]'
) = 1
Обратите внимание на следующее в предыдущем запросе:
Предложение WHERE выбирает только те строки из таблицы ProductDescription, которые удовлетворяют условию, указанному в отношении столбца типа xml CatalogDescription.
Метод exist() в предложении WHERE возвращает 1 (True), если XML не содержит элемента <Specifications>. Обратите внимание на использование функции not() (XQuery).
Функция sql:column() (XQuery) используется для импорта значения из столбца, имеющего тип, отличный от XML.
Этот запрос возвращает пустой набор строк.
Данный запрос указывает методы query() и exist() типа xml, и оба эти метода объявляют одинаковые пространства имен в прологе запроса. В этом случае для объявления префикса и использования его в запросе можно использовать предложение WITH XMLNAMESPACES.
WITH XMLNAMESPACES ('https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription' AS pd)
SELECT ProductModelID, CatalogDescription.query('
<Product
ProductModelID= "{ sql:column("ProductModelID") }"
/>
') AS Result
FROM Production.ProductModel
WHERE CatalogDescription.exist('
/pd:ProductDescription[not(pd:Specifications)]'
) = 1
См. также