型システム (XQuery)
XQuery は、スキーマ型に対しては厳密に型指定された言語で、型指定されていないデータに対しては厳密には型指定されていない言語です。XQuery の定義済みの型には、次のものがあります。
http://www.w3.org/2001/XMLSchema 名前空間に含まれている XML スキーマの組み込み型。
http://www.w3.org/2004/07/xpath-datatypes 名前空間で定義されている型。
このトピックでは、次の内容についても説明します。
型指定された値とノードの文字列値。
式から返されるシーケンス型の照合。
XML スキーマの組み込み型
XML スキーマの組み込み型には、xs という定義済みの名前空間プレフィックスが付いています。このような型には、xs:integer や xs:string などがあります。これらの組み込み型はすべてサポートされます。XML スキーマ コレクションを作成するときに、これらの型を使用できます。
型指定された XML のクエリを実行するとき、ノードの静的および動的な型は、クエリの対象の列または変数に関連付けられた XML スキーマ コレクションによって決まります。静的および動的な型の詳細については、「式コンテキストとクエリの評価 (XQuery)」を参照してください。たとえば、次のクエリは型指定された xml 列 (Instructions) に対して指定されています。この式では instance of を使用して、返される LotSize 属性の型指定された値が xs:decimal 型であることを確認しています。
SELECT Instructions.query('
DECLARE namespace AWMI="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelManuInstructions";
data(/AWMI:root[1]/AWMI:Location[@LocationID=10][1]/@LotSize)[1] instance of xs:decimal
') AS Result
FROM Production.ProductModel
WHERE ProductModelID=7
この型指定情報は、列に関連付けられた XML スキーマ コレクションによって提供されます。詳細については、「AdventureWorks データベースの xml データ型表現」を参照してください。
XPath データ型の名前空間で定義されている型
http://www.w3.org/2004/07/xpath-datatypes 名前空間で定義されている型には、xdt という定義済みのプレフィックスが付いています。これらの型には、次のことが当てはまります。
XML スキーマ コレクションを作成しているときは、これらの型を使用できません。これらの型は XQuery の型システムで使用され、XQuery と静的な型指定に使用されます。xdt 名前空間の xdt:untypedAtomic などのアトミック型にキャストできます。
型指定されていない XML のクエリでは、要素ノードの静的および動的な型は xdt:untyped で、属性値の型は xdt:untypedAtomic になります。query() メソッドの結果により、型指定されていない XML が生成されます。つまり、XML ノードはそれぞれ xdt:untyped と xdt:untypedAtomic として返されます。
xdt:dayTimeDuration 型と xdt:yearMonthDuration 型はサポートされません。
次の例では、型指定されていない XML 変数に対してクエリを指定しています。式 data(/a[1]) により、1 つのアトミック値のシーケンスが返されます。data() 関数により、要素 <a> の型指定された値が返されます。クエリ対象の XML は型指定されていないので、返される値は xdt:untypedAtomic 型です。したがって、instance of から True が返されます。
DECLARE @x xml
SET @x='<a>20</a>'
SELECT @x.query( 'data(/a[1]) instance of xdt:untypedAtomic' )
次の例の式 (/a[1]) は、型指定された値を取得するのではなく、要素 <a> という 1 つの要素のシーケンスを返します。instance of 式では要素をテストすることにより、式から返される値が xdt:untyped 型の要素ノードであることを確認します。
DECLARE @x xml
SET @x='<a>20</a>'
-- Is this an element node whose name is "a" and type is xdt:untyped.
SELECT @x.query( '/a[1] instance of element(a, xdt:untyped?)')
-- Is this an element node of type xdt:untyped.
SELECT @x.query( '/a[1] instance of element(*, xdt:untyped?)')
-- Is this an element node?
SELECT @x.query( '/a[1] instance of element()')
注意 |
---|
型指定された XML インスタンスにクエリを実行して、クエリ式に parent 軸が含まれるときは、結果のノードの静的な型情報は使用できなくなります。ただし、動的な型はノードに関連付けられたままです。 |
型指定された値と文字列値
どのノードにも型指定された値と文字列値があります。型指定された XML データの場合、型指定された値の型は、クエリ対象の列または変数に関連付けられた XML スキーマ コレクションによって提供されます。型指定されていない XML データの場合、型指定された値は xdt:untypedAtomic 型になります。
次のように data() 関数または string() 関数を使用して、ノードの値を取得できます。
data 関数 (XQuery)では、ノードの型指定された値が返されます。
string 関数 (XQuery)では、ノードの文字列値が返されます。
次の XML スキーマ コレクションでは、整数型の <root> 要素を定義しています。
CREATE XML SCHEMA COLLECTION SC AS N'
<schema xmlns="http://www.w3.org/2001/XMLSchema">
<element name="root" type="integer"/>
</schema>'
GO
次の例の式では、最初に /root[1] の型指定された値を取得してから、その値に 3 を加算しています。
DECLARE @x xml(SC)
SET @x='<root>5</root>'
SELECT @x.query('data(/root[1]) + 3')
次の例では、式の string(/root[1]) から文字列型の値が返されるので、式が失敗します。返された値は、オペランドとして数値型の値しか受け取らない算術演算子に渡されます。
-- Fails because the argument is string type (must be numeric primitive type).
DECLARE @x xml(SC)
SET @x='<root>5</root>'
SELECT @x.query('string(/root[1]) + 3')
次の例では、LaborHours 属性の合計を計算しています。data() 関数により、製品モデルのすべての <Location> 要素から LaborHours 属性の型指定された値が取得されます。Instruction 列に関連付けられた XML スキーマに従って、LaborHours は xs:decimal 型になります。
SELECT Instructions.query('
DECLARE namespace AWMI="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelManuInstructions";
sum(data(//AWMI:Location/@LaborHours))
') AS Result
FROM Production.ProductModel
WHERE ProductModelID=7
このクエリにより、結果として 12.75 が返されます。
注意 |
---|
この例では data() 関数を、説明のみを目的として明示的に使用しています。この関数を指定しないと、sum() では、ノードの型指定された値を取得する data() 関数が暗黙的に適用されます。 |