Поделиться через


Метод 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