XQuery での型キャストの規則
適用対象: SQL Server
次の W3C XQuery 1.0 and XPath 2.0 Functions and Operators 仕様の図は、組み込みのデータ型を示しています。 これには、組み込みのプリミティブ型と組み込みの派生型が含まれます。
このトピックでは、次のいずれかの方法を使用して、ある型から別の型にキャストするときに適用される型キャスト規則について説明します。
キャスト as または型コンストラクター関数 (たとえば、
xs:integer("5")
) を使用して明示的にキャストします。型の上位変換中に行われる暗黙のキャスト
明示的なキャスト
次の表は、組み込みのプリミティブ型間で許可される型キャストの概要を示しています。
組み込みのプリミティブ型は、テーブル内のルールに基づいて、別の組み込みプリミティブ型にキャストできます。
プリミティブ型は、そのプリミティブ型から派生した任意の型にキャストできます。 たとえば、 xs:decimal から xs:integer にキャストしたり、 xs:decimal から xs:long にキャストできます。
派生型は、組み込みのプリミティブ基本型まで、型階層内の先祖である任意の型にキャストできます。 たとえば、 xs:token から xs:normalizedString または xs:string にキャストできます。
ある派生型は、その先祖のプリミティブ型からキャストできる型であれば、任意のプリミティブ型にキャストできます。 たとえば、派生型である xs:integer を xs:string プリミティブ型にキャストできます。これは、 xs:decimal、 xs:integer のプリミティブ先祖を xs:string にキャストできるためです。
ある派生型は、その先祖のプリミティブ型からキャストできるプリミティブ型の先祖であれば、任意の派生型にキャストできます。 たとえば、 xs:integer から xs:token にキャストできます。これは、 xs:decimal から xs:string にキャストできるためです。
ユーザー定義型から組み込み型にキャストする場合の規則は、組み込み型の規則と同じです。 たとえば、xs:integer 型から派生したmyInteger型を定義できます。 その後、 myInteger を xs:token にキャストできます。これは、 xs:decimal を xs:string にキャストできるためです。
次の種類のキャストはサポートされていません。
リスト型間のキャストは許可されません。 これには、ユーザー定義リスト型と、 xs:IDREFS、 xs:ENTITIES、 xs:NMTOKENS などの組み込みリスト型の両方が含まれます。
xs:QName へのキャストはサポートされていません。
xs:NOTATION と完全に順序付けられた期間のサブタイプである xdt:yearMonthDuration および xdt:dayTimeDuration はサポートされていません。 したがって、これらの型間のキャストはサポートされません。
次の例は、明示的な型キャストを示しています。
例 A
次の例では、xml 型変数を照会します。 このクエリは、xs:string として型指定された単純型の値のシーケンスを返します。
declare @x xml
set @x = '<e>1</e><e>2</e>'
select @x.query('/e[1] cast as xs:string?')
go
例 B
次の例では、型指定された xml 変数をクエリします。 この例では、まず XML スキーマ コレクションを作成しています。 その後、XML スキーマ コレクションを使用して、型指定された xml 変数を作成します。 スキーマは、変数に割り当てられた XML インスタンスの型指定情報を提供します。 その後、変数に対してクエリを指定しています。
create xml schema collection myCollection as N'
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="root">
<xs:complexType>
<xs:sequence>
<xs:element name="A" type="xs:string"/>
<xs:element name="B" type="xs:string"/>
<xs:element name="C" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>'
go
次のクエリでは、ドキュメント インスタンス内の最上位レベル <root
> 要素の数がわからないため、静的エラーが返されます。
declare @x xml(myCollection)
set @x = '<root><A>1</A><B>2</B><C>3</C></root>
<root><A>4</A><B>5</B><C>6</baz></C>'
select @x.query('/root/A cast as xs:string?')
go
式にシングルトン <root
> 要素を指定すると、クエリは成功します。 このクエリは、xs:string として型指定された単純型の値のシーケンスを返します。
declare @x xml(myCollection)
set @x = '<root><A>1</A><B>2</B><C>3</C></root>
<root><A>4</A><B>5</B><C>6</C></root>'
select @x.query('/root[1]/A cast as xs:string?')
go
次の例では、xml 型変数に XML スキーマ コレクションを指定する document キーワードが含まれています。 これは、XML インスタンスが 1 つの最上位要素を持つドキュメントである必要があることを示します。 XML インスタンスに 2 つの <root
> 要素を作成すると、エラーが返されます。
declare @x xml(document myCollection)
set @x = '<root><A>1</A><B>2</B><C>3</C></root>
<root><A>4</A><B>5</B><C>6</C></root>'
go
最上位レベルの要素を 1 つだけ含むようにインスタンスを変更すると、クエリが機能します。 ここでも、クエリは xs:string として型指定された単純型の値のシーケンスを返します。
declare @x xml(document myCollection)
set @x = '<root><A>1</A><B>2</B><C>3</C></root>'
select @x.query('/root/A cast as xs:string?')
go
暗黙的キャスト
暗黙のキャストを使用できるのは、数値型と型指定されていないアトミック型だけです。 たとえば、次の min() 関数は、2 つの値の最小値を返します。
min(xs:integer("1"), xs:double("1.1"))
この例では、XQuery min() 関数に渡される 2 つの値は異なる型です。 したがって、暗黙的な変換は、integer型が倍に昇格され 2 つの値が比較される場合に実行されます。
この例のような型の上位変換は、次の規則に従って行われます。
組み込みの派生数値型は、その基本型に昇格できます。 たとえば、 integer を decimal に昇格できます。
decimalはfloat,に昇格することができ、floatはに昇格することができます。
暗黙のキャストを使用できるのは数値型だけなので、次のキャストは許可されません。
文字列型間の暗黙のキャストは許可されません。 たとえば、2 つの string 型が必要であり、 string と token を渡すと、暗黙的なキャストは行われず、エラーが返されます。
数値型から文字列型への暗黙的なキャストは許可されません。 たとえば、文字列型のパラメーターが必要な関数に整数型の値を渡すと、暗黙のキャストは行われず、エラーが返されます。
値のキャスト
ある型から別の型へキャストすると、実際の値は元の型の値空間からキャスト先の型の値空間に変換されます。 たとえば、xs:decimal から xs:double にキャストすると、decimal 値が double 値に変換されます。
次に、いくつかの変換の規則を示します。
文字列または型指定されていないAtomic 型から値をキャストする
string または untypedAtomic 型にキャストされる値は、キャスト先の型の規則に基づいて値が評価されるのと同じ方法で変換されます。 これには、最終的なパターンと空白の処理規則が含まれます。 たとえば、次のキャストは成功し、double 値 1.1e0 が生成されます。
xs:double("1.1")
文字列型または型指定されていないAtomic 型から xs:base64Binary や xs:hexBinary などのバイナリ型にキャストする場合、入力値はそれぞれ base64 または hex でエンコードする必要があります。
文字列型または型指定されていないAtomic 型への値のキャスト
文字列型または型指定されていないAtomic 型にキャストすると、値は XQuery の正規語彙表現に変換されます。 これは、入力時に特定のパターンや他の制約に従っていた値が、制約どおりに表記されない可能性があることを意味します。 このことをユーザーに通知するために、SQL Server では、型がスキーマ コレクションに読み込まれるときに警告を表示することで、型制約が問題になる可能性がある型にフラグを設定します。
xs:float 型、xs:double 型、またはこれらのサブタイプの値を string 型または untypedAtomic 型にキャストする場合、値は科学的表記法で表現されます。 これは、値の絶対値が 1.0E-6 未満であるか、1.0E6 以上である場合にのみ行われます。 つまり、0 は科学的表記法で 0.0E0 にシリアル化されます。
たとえば、 xs:string(1.11e1)
は "11.1"
文字列値を返しますが、 xs:string(-0.00000000002e0)
は文字列値 "-2.0E-11"
返します。
xs:base64Binary や xs:hexBinary などバイナリ型から string 型または untypedAtomic 型にキャストする場合、バイナリ値はそれぞれ base64 または hex エンコード形式で表現されます。
数値型への値のキャスト
ある数値型の値を別の数値型の値にキャストする場合、値は文字列のシリアル化を行わずに、ある値空間から他方の値空間にマップされます。 値がターゲット型の制約を満たさない場合は、次の規則が適用されます。
ソース値が既に数値であり、ターゲットの型が xs:float またはそのサブタイプであり、-INF または INF 値を許可するサブタイプであり、ソース数値のキャストによってオーバーフローが発生する場合、値が正の場合は INF にマップされ、値が負の場合は -INF にマップされます。 ターゲット型が INF または -INF を許可せず、オーバーフローが発生した場合、キャストは失敗し、SQL Server のこのリリースの結果は空のシーケンスになります。
元の値が既に数値型で、キャスト先の型が 0、-0e0、または 0e0 を許容する数値型の場合に、元の数値がキャスト後オーバーフローするようなときは、値が次のようにマップされます。
キャスト先の型が decimal の場合、値は 0 にマップされます。
値が負のアンダーフローになる場合、値は -0e0 にマップされます。
値が float 型または double ターゲット型の正のアンダーフローである場合、値は 0e0 にマップされます。
ターゲット型の値空間にゼロが含まれていない場合、キャストは失敗し、結果は空のシーケンスになります。
値を xs:float、xs:double、またはそのサブタイプなどのバイナリ浮動小数点型にキャストすると、有効桁数が失われる可能性があることに注意してください。
実装の制限事項
制限事項は次のとおりです。
浮動小数点値 NaN はサポートされていません。
キャスト可能な値は、ターゲット型の実装制限によって制限されます。 たとえば、負の年の日付文字列を xs:date にキャストすることはできません。 実行時に値が指定された場合、このようなキャストでは、(実行時エラーになるのではなく) 空のシーケンスが返されます。