string-length 関数 (XQuery)
文字列の長さを文字数として返します。
構文
fn:string-length() as xs:integer
fn:string-length($arg as xs:string?) as xs:integer
引数
- $arg
長さを計算する対象となるソース文字列です。
説明
$arg の値が空のシーケンスの場合は、返される xs:integer の値は 0 になります。
値にサロゲート文字 2 文字で表される 3 バイトの Unicode 文字が含まれている場合、SQL Server はサロゲート文字 1 つを 1 文字として計算します。
引数のない string-length() は、述語内でしか使用できません。たとえば、次のクエリでは <ROOT> 要素が返されます。
declare @x xml;
set @x='<ROOT>Hello</ROOT>';
select @x.query('/ROOT[string-length()=5]');
例
このトピックでは、AdventureWorks2008R2 データベースのさまざまな xml 型の列に格納されている XML インスタンスに対して実行する XQuery の例について説明します。これらの各列の概要については、「AdventureWorks2008R2 データベースの xml データ型表現」を参照してください。
A. XQuery の string-length() 関数を使用して、長い概要説明のある製品を取得する
次のクエリでは、概要説明が 50 文字を超える製品の製品 ID、概要説明の長さ、概要自体 (<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 を構築し、XML ドキュメントからデータを取得するために必要な XQuery 式を指定しています。
結果の一部を次に示します。
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>
...
B. XQuery の string-length() 関数を使用して、保証内容が非常に短い製品を取得する
次のクエリは、保証内容の記述が 20 文字に満たない製品の製品 ID、長さ、保証内容の記述、<Warranty> 要素自体を含む XML 取得します。
保証は製品の特徴の 1 つです。<Features> 要素の後に、省略可能な <Warranty> 子要素が続きます。
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 ループを指定しています。<ProductDescription> 要素の ProductModelID 属性を取得するので、外部 FOR ループが必要です。また、保証内容の記述が 20 文字未満の製品のみを取得するので、内部 FOR ループも必要です。
結果の一部を次に示します。
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>
...