Функция string-length (XQuery)
Возвращает длину строки в символах.
Синтаксис
fn:string-length() as xs:integer
fn:string-length($arg as xs:string?) as xs:integer
Аргументы
- $arg
Строка источника, длина которой подлежит вычислению.
Замечания
Если значение свойства $arg представляет собой пустую последовательность, то элементу xs:integer возвращается значение 0.
Поведение суррогатных пар в функциях XQuery зависит от уровня совместимости базы данных. Если уровень совместимости 110 или выше, каждая суррогатная пара рассматривается как один символ. При более низких уровнях совместимости они рассматриваются как два символа. Дополнительные сведения см. в разделах Уровень совместимости инструкции ALTER DATABASE (Transact-SQL) и Поддержка параметров сортировки и Юникода.
Если значение содержит 4-байтовый символ в Юникоде, представленный двумя суррогатными символами, SQL Server будет подсчитывать суррогатные символы по отдельности.
Функция string-length() без параметра может использоваться только внутри предиката. Например, следующий запрос возвращает элемент <ROOT>:
DECLARE @x xml;
SET @x='<ROOT>Hello</ROOT>';
SELECT @x.query('/ROOT[string-length()=5]');
Дополнительные символы (суррогатные пары)
Поведение суррогатных пар в функциях XQuery зависит от уровня совместимости базы данных и, в некоторых случаях, от URI-кода пространства имен по умолчанию для функций. Дополнительные сведения см. в пункте «Функции XQuery учитывают суррогаты» раздела Критические изменения в функциях компонента ядра СУБД в SQL Server 2012. Также см. разделы Уровень совместимости инструкции ALTER DATABASE (Transact-SQL) и Поддержка параметров сортировки и Юникода.
Примеры
В этом разделе представлены примеры запросов XQuery к экземплярам XML, хранящимся в различных столбцах типа xml в базе данных AdventureWorks.
А.Использование функции string-length() языка XQuery для получения продуктов с длинными сводными описаниями
Для продуктов, чье сводное описание длиннее 50 символов, следующий запрос получает код продукта, длину сводного описания и сводное описание — элемент <Summary>.
WITH XMLNAMESPACES ('https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription' as pd)
SELECT CatalogDescription.query('
<Prod ProductID= "{ /pd:ProductDescription[1]/@ProductModelID }" >
<LongSummary SummaryLength =
"{string-length(string( (/pd:ProductDescription/pd:Summary)[1] )) }" >
{ string( (/pd:ProductDescription/pd:Summary)[1] ) }
</LongSummary>
</Prod>
') as Result
FROM Production.ProductModel
WHERE CatalogDescription.value('string-length( string( (/pd:ProductDescription/pd:Summary)[1]))', 'decimal') > 200;
В предыдущем запросе обратите внимание на следующее.
Условие в предложении WHERE получает только строки, в которых описания сводки, хранимые в XML-документе, длиннее 200 символов. При этом используется метод value() (тип данных XML).
Предложение SELECT просто выстраивает необходимый код XML. При этом используется метод query() (тип XML-данных), чтобы создать XML и указать необходимое выражение XQuery для получения данных из XML-документа.
Это промежуточный результат:
Result
-------------------
<Prod ProductID="19">
<LongSummary SummaryLength="214">Our top-of-the-line competition
mountain bike. Performance-enhancing options include the
innovative HL Frame, super-smooth front suspension, and
traction for all terrain.
</LongSummary>
</Prod>
...
Б.Использование функции string-length() языка XQuery для получения продуктов с короткими описаниями гарантии
Для продуктов, чьи гарантийные описания меньше 20 символов в длину, следующий запрос получает XML, который включает идентификатор продукта, длину, гарантийное описание гарантии и элемент <Warranty> как таковой.
Гарантия — это одна из характеристик продукта. Необязательный дочерний элемент <Warranty> следует после элемента <Features>.
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.query('
for $ProdDesc in /pd:ProductDescription,
$pf in $ProdDesc/pd:Features/wm:Warranty
where string-length( string(($pf/wm:Description)[1]) ) < 20
return
<Prod >
{ $ProdDesc/@ProductModelID }
<ShortFeature FeatureDescLength =
"{string-length( string(($pf/wm:Description)[1]) ) }" >
{ $pf }
</ShortFeature>
</Prod>
') as Result
FROM Production.ProductModel
WHERE CatalogDescription.exist('/pd:ProductDescription')=1;
В приведенном запросе обратите внимание на следующие моменты.
pd и wm — это используемые в данном запросе префиксы пространства имен. Они определяют то же пространство имен, что используется в запрашиваемом документе;
XQuery указывает вложенный цикл FOR. Требуется внешний цикл FOR, так как нужно получить атрибуты ProductModelID элемента <ProductDescription>. Внутренний цикл FOR требуется, так как нужны только продукты, имеющие описания характеристик гарантии меньше 20 символов в длину.
Промежуточный результат:
Result
-------------------------
<Prod ProductModelID="19">
<ShortFeature FeatureDescLength="15">
<wm:Warranty
xmlns:wm="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelWarrAndMain">
<wm:WarrantyPeriod>3 years</wm:WarrantyPeriod>
<wm:Description>parts and labor</wm:Description>
</wm:Warranty>
</ShortFeature>
</Prod>
...