XQuery での型キャストの規則

適用対象:SQL Server

次の W3C XQuery 1.0 and XPath 2.0 Functions and Operators 仕様の図は、組み込みのデータ型を示しています。 これには、組み込みのプリミティブ型と組み込みの派生型が含まれます。

XQuery 1.0 型階層

このトピックでは、次のいずれかの方法を使用して、ある型から別の型にキャストするときに適用される型キャスト規則について説明します。

  • としてキャストするか、型コンストラクター関数 (例: xs:integer("5")) を使用して行う明示的なキャスト。

  • 型の上位変換中に行われる暗黙のキャスト

明示的なキャスト

次の表は、組み込みのプリミティブ型間でキャストできる型の概要を示しています。

XQuery のキャスト規則について説明します。

  • 組み込みのプリミティブ型は、テーブル内のルールに基づいて、別の組み込みプリミティブ型にキャストできます。

  • プリミティブ型は、そのプリミティブ型から派生した任意の型にキャストできます。 たとえば、xs:decimal から xs:integer に、または xs:decimal から xs:long にキャストできます。

  • 派生型は、組み込みのプリミティブ基本型まで、型階層内の先祖である任意の型にキャストできます。 たとえば、 xs:token から xs:normalizedString または xs:string にキャストできます。

  • ある派生型は、その先祖のプリミティブ型からキャストできる型であれば、任意のプリミティブ型にキャストできます。 たとえば、xs:decimal、xs:integer のプリミティブ先祖は xs:string にキャストできるため、派生型である xs:integerxs:string にキャストできます。

  • ある派生型は、その先祖のプリミティブ型からキャストできるプリミティブ型の先祖であれば、任意の派生型にキャストできます。 たとえば、xs:integer から xs:token にキャストできます。これは、xs:decimal から xs:string にキャストできるためです。

  • ユーザー定義型から組み込み型にキャストする場合の規則は、組み込み型の規則と同じです。 たとえば、xs:integer 型から派生した myInteger 型を定義できます。 次に、xs:decimal を xs:string にキャストできるため、myIntegerxs:token にキャストできます。

次の種類のキャストはサポートされていません。

  • リスト型間のキャストは許可されません。 これには、ユーザー定義のリスト型と、xs:IDREFS、xs:ENTITIES、xs:NMTOKENS などの組み込みリスト型の両方が含まれます。

  • xs:QName へのキャストまたは 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 つの値は異なる型です。 したがって、整数型が double に昇格され、2 つのdouble 値が比較される場合、暗黙的な変換が実行されます。

この例のような型の上位変換は、次の規則に従って行われます。

  • 組み込みの派生数値型は、その基本型に昇格できます。 たとえば、 integer10 進数に昇格できます。

  • 10 進数を float に昇格させfloatdouble に昇格できます。

暗黙のキャストを使用できるのは数値型だけなので、次のキャストは許可されません。

  • 文字列型間の暗黙のキャストは許可されません。 たとえば、2 つの 文字列 型が必要で、 文字列トークンを渡した場合、暗黙的なキャストは行われず、エラーが返されます。

  • 数値型から文字列型への暗黙的なキャストは許可されません。 たとえば、文字列型のパラメーターが必要な関数に整数型の値を渡すと、暗黙のキャストは行われず、エラーが返されます。

値のキャスト

ある型から別の型へキャストすると、実際の値は元の型の値空間からキャスト先の型の値空間に変換されます。 たとえば、xs:decimal から xs:double にキャストすると、decimal 値が double 値に変換されます。

次に、いくつかの変換の規則を示します。

文字列型または型指定されていないAtomic 型から値をキャストする

string または untypedAtomic 型にキャストされる値は、キャスト先の型の規則に基づいて値が評価されるのと同じ方法で変換されます。 これには、最終的なパターンと空白の処理規則が含まれます。 たとえば、次のキャストは成功し、double 値 1.1e0 が生成されます。

xs:double("1.1")

文字列型または untypedAtomic 型から xs:base64Binary や xs:hexBinary などのバイナリ型にキャストする場合、入力値はそれぞれ base64 または hex でエンコードする必要があります。

値を文字列型または型指定されていないAtomic 型にキャストする

文字列型または untypedAtomic 型にキャストすると、その値が 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 にマップされます。

    ターゲット型の値空間に 0 が含まれていない場合、キャストは失敗し、結果は空のシーケンスになります。

    値を xs:float、xs:double、またはそのサブタイプなどのバイナリ浮動小数点型にキャストすると、有効桁数が失われる可能性があることに注意してください。

実装の制限事項

制限事項は次のとおりです。

  • 浮動小数点値 NaN はサポートされていません。

  • キャスト可能な値は、ターゲット型の実装の制限によって制限されます。 たとえば、負の年の日付文字列を xs:date にキャストすることはできません。 実行時に値が指定された場合、このようなキャストでは、(実行時エラーになるのではなく) 空のシーケンスが返されます。

参照

XML データのシリアル化の定義