XPath のデータ型 (SQLXML 4.0)
適用対象: SQL Server Azure SQL Database
Microsoft SQL Server、XPath、および XML スキーマ (XSD) のデータ型は非常に異なります。 たとえば、XPath には整数または日付のデータ型はありませんが、SQL Server と XSD には多くのデータ型があります。 XSD では時間値にナノ秒精度が使用され、SQL Server では最大 1/300 秒の精度が使用されます。 このため、あるデータ型から別のデータ型へのマッピングが常に可能であるとは限りません。 SQL Server データ型と XSD データ型のマッピングの詳細については、「 Data 型の強制型と sql:datatype Annotation (SQLXML 4.0)」を参照してください。
XPath には、 string、 number、および boolean の 3 つのデータ型があります。 number データ型は常に IEEE 754 倍精度浮動小数点です。 SQL Serverfloat(53) データ型は、XPath number に最も近いデータ型です。 ただし、 float(53) は正確には IEEE 754 ではありません。 たとえば、非数 (NaN) も無限大も使用されません。 数値以外の文字列を number に変換しようとして 0 で除算しようとするとエラーが発生します。
XPath 変換
OrderDetail[@UnitPrice > "10.0"]
などの XPath クエリを使用する場合は、データ型の変換を暗黙的に行うか明示的に行うかによって、クエリの意味が微妙に変わります。 このため、XPath データ型の実装方法について理解しておくことが重要です。 XPath 言語仕様である XML パス言語 (XPath) バージョン 1.0 W3C 提案推奨事項 8 1999 年 10 月 8 日は、 http://www.w3.org/TR/1999/PR-xpath-19991008.htmlの W3C Web サイトで確認できます。
XPath の演算子は、次の 4 つのカテゴリに分けられます。
論理演算子 (and、or)
関係演算子 (<、 >、 <=、 >=)
等価演算子 (=、!=)
算術演算子 (+、-、*、div、mod)
各カテゴリの演算子では、それぞれ異なる方法で各自のオペランドが変換されます。 XPath の演算子では、必要に応じて各自のオペランドが暗黙的に変換されます。 算術演算子は、オペランドを number に変換し、結果として数値を返します。 ブール演算子は、オペランドを boolean に変換し、ブール値になります。 関係演算子と等価演算子では、ブール値が得られます。 ただし、次の表に示すように、オペランドの変換元のデータ型に応じて、それぞれ異なる変換規則が使用されます。
オペランド | 関係演算子 | 等値演算子 |
---|---|---|
両方のオペランドがノード セットの場合 | 1 つのセットにノードがあり、2 つ目のセットにノードが存在し、 string 値の比較が TRUE の場合にのみ TRUE。 | 同じ。 |
1 つはノード セット、もう 1 つは string です。 | ノード セット内にノードが存在する場合に限り、 number に変換した場合、 string との比較 number は TRUE になります。 | stringに変換されるときに、stringとの比較が TRUE になるように、ノード セット内にノードがある場合にのみ TRUE。 |
1 つはノード セット、もう 1 つは number です。 | numberに変換されるときに、numberとの比較が TRUE になるように、ノード セット内にノードがある場合にのみ TRUE。 | 同じ。 |
1 つはノード セットで、もう 1 つは boolean です。 | booleanにnumberに変換された場合、ノード セット内にノードがある場合にのみ TRUE、booleannumber に変換されます。 | booleanに変換されるときに、booleanとの比較が TRUE になるように、ノード セット内にノードがある場合にのみ TRUE。 |
どちらもノード セットでない場合 | 両方のオペランドを number に変換し、比較します。 | 両方のオペランドを共通のデータ型に変換し比較。 いずれかの値が boolean の場合は boolean に変換いずれかが number の場合は number、それ以外の場合は string に変換します。 |
Note
XPath 関係演算子は常にオペランドを number に変換するため、 string 比較はできません。 日付の比較を含めるには、 SQL Server 2000 では、XPath 仕様に対してこのバリエーションが提供されます。リレーショナル演算子が string を string、ノード セットを string、または文字列値ノード セットに設定すると、 string 比較 ( 番号 比較ではない) が実行されます。
ノード セット変換
ノード セット変換は常に直感的なものとは限りません。 ノード セットは、セット内の最初のノードのみの文字列値を取得することでstring に変換されます。 ノード セットは、string に変換してnumber に変換し、string を number に変換します。 ノード セットは、存在をテストすることによって boolean に変換されます。
Note
SQL Server では、ノード セットで位置指定の選択は実行されません。たとえば、XPath クエリ Customer[3]
は 3 番目の顧客を意味します。この種類の位置選択は SQL Server ではサポートされていません。 したがって、XPath 仕様で説明されているように、node-set-to-string または node-set-to-number 変換は実装されません。 SQL Server では、XPath 仕様で "first" セマンティクスが指定されている場合は、どこでも "any" セマンティクスが使用されます。 たとえば、W3C XPath 仕様に基づいて、XPath クエリ Order[OrderDetail/@UnitPrice > 10.0]
は、最初の OrderDetail UnitPrice が 10.0 より大きい注文を選択します。 SQL Server では、この XPath クエリは、UnitPrice が 10.0 より大きい任意の OrderDetail を持つ注文を選択します。
booleanへの変換により存在テストが生成されます。したがって、XPath クエリ Products[@Discontinued=true()]
は、SQL 式 "Products.Discontinued = 1" ではなく、SQL 式 "Products.Discontinued is not null" に相当します。 クエリを後者の SQL 式と等価にするには、最初にノード セットを非boolean 型 ( number など) に変換します。 たとえば、Products[number(@Discontinued) = true()]
のようにします。
大半の演算子は、ノード セット内の 1 つ以上のノードに対して TRUE であれば TRUE となるように定義されているので、これらの演算はノード セットが空の場合は常に FALSE となります。 したがって、A が空の場合、A = B
と A != B
は両方とも FALSE になり、not(A=B)
と not(A!=B)
は TRUE になります。
通常、データベース内の列の値が null でない場合、列にマップされる属性または要素が存在。 行にマップされる要素は、子が存在する場合に存在します。
Note
is-constant で注釈が付けられた要素は常に存在します。 したがって、XPath 述語は、 is-constant 要素では使用できません。
ノード セットを string または number に変換すると、注釈付きスキーマでその XDR 型 (存在する場合) が検査され、その型が使用されて、必要な変換が決定されます。
XDR データ型から XPath データ型へのマッピング
ノードの XPath データ型は、次の表に示すように、スキーマの XDR データ型から派生します (ノード EmployeeID は説明のために使用されます)。
XDR データ型 | 同等の XPath データ型 |
使用される SQL Server 変換 |
---|---|---|
Nonebin.base64bin.hex | 該当なし | NoneEmployeeID |
boolean | boolean | CONVERT(bit, EmployeeID) |
number、int、float,i1、i2、i4、i8、r4、r8ui1、ui2、ui4、ui8 | 数値 | CONVERT(float(53), EmployeeID) |
id、idref、idrefsentity、entities、enumerationnotation、nmtoken、nmtokens、chardate、Timedate、Time.tz、string、uri、uuid | string | CONVERT(nvarchar(4000), EmployeeID, 126) |
fixed14.4 | N/A (XDR データ型 fixed14.4 に相当する XPath のデータ型はありません) | CONVERT(money, EmployeeID) |
日付 | string | LEFT(CONVERT(nvarchar(4000), EmployeeID, 126), 10) |
time time.tz |
string | SUBSTRING(CONVERT(nvarchar(4000), EmployeeID, 126), 1 + CHARINDEX(N'T', CONVERT(nvarchar(4000), EmployeeID, 126)), 24) |
日付と時刻の変換は、値が SQL Server datetime データ型または string を使用してデータベースに格納されるかどうかに関係なく機能するように設計されています。 SQL Serverdatetime データ型は timezone を使用せず XML time データ型よりも有効桁数が小さいことに注意してください。 timezoneデータ型または追加の有効桁数を含めるには、string 型を使用して SQL Server にデータを格納します。
ノードが XDR データ型から XPath データ型に変換される場合は、1 つの XPath データ型から別の XPath データ型へ、追加の変換が必要になることがあります。 たとえば、次の XPath クエリを考えてみます。
(@m + 3) = 4
@mが fixed14.4 XDR データ型の場合、XDR データ型から XPath データ型への変換は次を使用して行われます。
CONVERT(money, m)
この変換では、ノード m
は fixed14.4 から money に変換されます。 しかし、値 3 を加算するには追加の変換が必要になります。
CONVERT(float(CONVERT(money, m))
この XPath 式は、次のように評価されます。
CONVERT(float(CONVERT(money, m)) + CONVERT(float(53), 3) = CONVERT(float(53), 3)
次の表に示すように、これは、リテラルや複合式など、他の XPath 式に適用される変換と同じです。
X が不明 | X は文字列です | X は数値です | X はブール値です | |
---|---|---|---|---|
string(X) | CONVERT (nvarchar(4000), X, 126) | - | CONVERT (nvarchar(4000), X, 126) | CASE WHEN X THEN N'true' ELSE N'false' END |
number(X) | CONVERT (float(53), X) | CONVERT (float(53), X) | - | CASE WHEN X THEN 1 ELSE 0 END |
boolean(X) | - | LEN(X) > 0 | X != 0 | - |
例
A. XPath クエリ内のデータ型を変換する
注釈付き XSD スキーマに対して指定された次の XPath クエリでは、クエリは EmployeeID E-1 の属性値を持つすべての Employee ノードを選択します。ここで、"E-" は sql:id-prefix 注釈を使用して指定されたプレフィックスです。
Employee[@EmployeeID="E-1"]
クエリ内の述語は、次の SQL 式と等価です。
N'E-' + CONVERT(nvarchar(4000), Employees.EmployeeID, 126) = N'E-1'
EmployeeID は id (idref の 1 つです。 idrefs、nmtoken、nmtokensなど) XSD スキーマのデータ型の値、EmployeeID は、前述の変換規則を使用して string XPath データ型に変換されます。
CONVERT(nvarchar(4000), Employees.EmployeeID, 126)
文字列に "E-" プレフィックスが追加され、結果が N'E-1'
と比較されます。
B. XPath クエリ内で複数のデータ型変換を実行する
注釈付き XSD スキーマに対して指定される XPath クエリ OrderDetail[@UnitPrice * @OrderQty > 98]
を考えてみます。
この XPath クエリは、述語@UnitPrice * @OrderQty > 98
を満たすすべての<OrderDetail>要素を返します。 UnitPriceに注釈付けされたスキーマのfixed14.4データ型で注釈が付けられた場合、この述語は SQL 式と同じです。
CONVERT(float(53), CONVERT(money, OrderDetail.UnitPrice)) * CONVERT(float(53), OrderDetail.OrderQty) > CONVERT(float(53), 98)
XPath クエリ内の値を変換するとき、最初の変換では、XDR データ型を XPath データ型に変換します。 前の表で説明したように、 UnitPrice の XSD データ型は fixed14.4 であるため、これが最初に使用される変換です。
CONVERT(money, OrderDetail.UnitPrice))
算術演算子はオペランドを number XPath データ型に変換するため、2 つ目の変換 (ある XPath データ型から別の XPath データ型への変換) が適用され、値が float(53) に変換されます (float(53) は XPath number データ型に近くなります)。
CONVERT(float(53), CONVERT(money, OrderDetail.UnitPrice))
OrderQty 属性に XSD データ型がないと仮定すると、OrderQty は 1 回の変換で number XPath データ型に変換されます。
CONVERT(float(53), OrderDetail.OrderQty)
同様に、値 98 は number XPath データ型に変換されます。
CONVERT(float(53), 98)
Note
スキーマで使用される XSD データ型がデータベース内の基になる SQL Server データ型と互換性がない場合、または不可能な XPath データ型変換が実行された場合、SQL Server はエラーを返す可能性があります。 たとえば、 EmployeeID 属性に id-prefix 注釈が付いている場合、XPath Employee[@EmployeeID=1]
はエラーを生成します。これは、 EmployeeID に id-prefix 注釈があり、 numberに変換できないためです。