非 Unicode データベースでの XML の使用に関するガイドライン

pureXML® フィーチャーを使用すると、データベースが Unicode コード・ページを使用していない場合でも、そのデータベースから XML データを保管および取得することができます。 このトピックでは、そのような状況でデータが破損または損失する可能性を最小限にするために XML データを安全に保管する方法について説明します。

XML 文書をリレーショナル・データベース表に保管する場合には、データの整合性を保つために、保管する XML 文書のエンコードとターゲット・データベースのエンコードの両方について注意する必要があります。 これらの 2 つのエンコードが一致すれば、データは常に安全に挿入できます。 これらの 2 つのエンコードが一致しないと、文字変換が必要になります。 特に、XML 文書中の文字に対応するコード・ポイントがターゲット・データベースのコード・ページに存在しない場合は、その文字が挿入時に置換されます。 さらに、XML 処理中にもまた別の文字置換が実行されます。例えば、XML データを使用するキャストや比較演算の実行中などです。 このような演算は常に Unicode 形式で管理されるため、非 Unicode データベース内の文字は、演算中に UTF-8 形式に変換されなければなりません。 文字置換が必要になる状況では、置換後のデータに対する演算で 予期しない結果が返され、データベースから取得された XML データに正しくない値が含まれることがあります。

ここでは、保管された XML データとそのデータを使用する演算の整合性を保証するためにコード・ページ変換を安全に回避できるように、さまざまなエンコードのシナリオで XML データを挿入したり照会したりする方法について説明します。

内容

XML 文書の挿入およびコード・ページ変換

文字データ・タイプ (FOR BIT DATA タイプではない CHAR、VARCHAR、または CLOB のデータ・タイプ) のホスト変数またはパラメーター・マーカーを使用して XML データが Db2® データベース・サーバーに挿入されるときに、データベースのコード・ページが要求を発行するクライアントまたはアプリケーションのコード・ページと異なる場合は必ず、コード・ページ変換が行われます。 挿入された文字データがデータベース・コード・ページから Unicode (XML データが内部的に管理される形式) に変換される際に、2 度目の変換が発生します。

以下の表は、データベースとクライアントまたはアプリケーションから挿入された XML 文書ストリングとの間の、さまざまな可能なエンコード方式の組み合わせを示しています。 クライアントは XML データを文字データ・タイプを介して挿入するので、XML 文書エンコードはクライアント・コード・ページと同じです。 それぞれの組み合わせについて、XML 文書挿入中のコード・ページ変換の影響、およびその結果として生じる文字置換の可能性が説明されています。
表 1. データベースと挿入された XML 文書ストリングとの間のエンコード・シナリオ
シナリオ XML 文書のエンコード方式 データベースのエンコード方式 コード・ページは一致しますか ?
1秒. Unicode (UTF-8) Unicode (UTF-8) はい
2 非 Unicode Unicode (UTF-8) なし
3 非 Unicode 非 Unicode はい
4 Unicode (UTF-8) 非 Unicode なし
5 非 Unicode 非 Unicode なし
  1. シナリオ 1 で、XML 文書およびデータベースは Unicode エンコードを共有します。 XML 文書が挿入されるときに、文字変換は生じません。 この方法で XML データを挿入することが、常に安全です。
  2. シナリオ 2 で、非 Unicode の XML 文書は Unicode データベースに挿入されるために UTF-8 に変換されます。 この処理では、文字置換は生じません。 この方法で XML データを挿入することが、常に安全です。
  3. シナリオ 3 で、XML 文書およびデータベースは同じ非 Unicode エンコードを共有します。 この場合、XML 文書にはデータベース・コード・ページの一部であるコード・ポイントだけが含まれるので、コード・ページ変換中に文字置換は発生しません。 この方法で XML データを挿入することが、常に安全です。
  4. シナリオ 4 で、Unicode の XML 文書が非 Unicode のデータベースに挿入されます。 文字データ・タイプの XML 文書がホスト変数またはパラメーター・マーカーを介して UTF-8 クライアントまたはアプリケーションから挿入される場合、 コード・ページ変換が生じます。 データベース・コード・ページ内に一致するコード・ポイントのない XML 文書内の文字は置換されます。
  5. シナリオ 5 で、XML 文書がデータベース・サーバーに挿入されるとき、 それら 2 つのエンコード方式が異なり、どちらも UTF-8 ではない場合について示されます。 この場合、シナリオ 4 のようにして XML 文書が文字データ・タイプを使用して挿入されるのであれば、XML 文書にデータベース・コード・ページで無効な文字が含まれる場合に文字置換が発生します。

XML データを非 Unicode のデータベースに安全に挿入する

XML データの保全性を保証する上で最も安全な方法は、Unicode データベースを使用することです。 しかし、それが不可能な場合、文字置換の発生を回避する他の方法もあります。 以下のリストは、Unicode データベースが使用される場合と使用されない場合について、XML データを安全に挿入するためのさまざまな方法を示しています。

Unicode データベースを使用するか、またはデータベースとクライアントとが同じエンコード方式を使用することを確認します。
表 1に示されているように、XML データのコード・ページ変換の問題は、以下の場合には常に回避されます。
  • データベースが Unicode の場合
  • Unicode であってもなくても、データベースとクライアントとが同じエンコード方式を共有する場合
文字データ・タイプと共にホスト変数またはパラメーター・マーカーを使用することを避けます。

Unicode データベースを使用できないとき、XML データのコード・ページ変換は、 タイプ XML または他のバイナリー・データ・タイプのホスト変数またはパラメーター・マーカーを使用して XML データをバインドすることによっても避けられます。 つまり、XML データに CHAR、 VARCHAR、または CLOB 以外のデータ・タイプを指定すると、それをクライアントまたはアプリケーション・コード・ページから Unicode に直接渡すことが可能になり、データベース・コード・ページへの変換が回避されます。

ENABLE_XMLCHAR 構成パラメーターによって、文字データ・タイプを介して挿入することを許可するかどうかを制御できます。 ENABLE_XMLCHAR を「NO」に設定すると、XML 文書の挿入中に文字データ・タイプの使用がブロックされるので、文字置換が発生する可能性が回避され、保管される XML データの保全性が保証されます。 BLOB および FOR BIT DATA タイプは、コード・ページ変換に関して安全なので、引き続き許可されます。 デフォルトでは、ENABLE_XMLCHAR は「YES」に設定されているので、文字データ・タイプの挿入は可能になっています。

Unicode データベースが使用されるときはコード・ページ変換が問題とならないので、 この場合 ENABLE_XMLCHAR 構成パラメーターは効果がありません。 ENABLE_XMLCHAR の設定に関係なく、XML 文書の挿入には文字データ・タイプを使用できます。

データベース・コード・ページに含まれない文字に対して文字エンティティー参照を使用します。
コード・ページ変換を避けることができず、XML データ・ストリームに文字データ・タイプを使用しなければならない場合、XML 文書内のすべての文字に対してデータベース・コード・ページ内に一致するコード・ポイントがあることを確認するのが最善です。 ターゲット・データベース内に一致するコード・ポイントがない XML データ内の文字については、 文字エンティティー参照を使用して文字の Unicode コード・ポイントを指定できます。 文字エンティティー参照ではコード・ページ変換が常に回避されるので、 正しい文字が XML データ内に保持されます。 例えば、文字エンティティー参照 > および > は、それぞれ、より大記号 ("> ") に相当する 16 進数および 10 進数です。

非 Unicode データベースでの XML データの照会

XML データをデータベースに挿入する際に、XML データの関係する照会の実行中のデータ保全性を保証する上で最も安全な方法は、Unicode データベースを使用することです。 それが不可能な場合、すべての XML データがデータベース・コード・ページで表現可能であることを確認することにより、またはデータベース・コード・ページ内にない文字の文字エンティティー参照を使用することにより、文字置換を回避できます。

データベース・コード・ページで表現できない文字を含む XML 内容が照会に含まれている場合、次の 2 つのタイプの文字置換が発生することがあり、照会の結果が予期しないものとなる可能性があります。
デフォルトの置換文字による置換
コード・ページに対するデフォルトの置換文字は、 XML データ内にある対応不可の文字の代わりに導入されます。 例えば、中国語の文字が ASCII エンコード・データベース (ISO-8859-1) に渡される場合、クライアント上で表示された時点で元の文字は、ASCII コード・ポイント 0x1A に置換されます。 それは、通常疑問符 ('?') として表示される制御文字です。 XML データがデータベース・コード・ページから Unicode に変換されるとき、置換文字は保存されます。
相当する文字のうち最も近いものによる置換 (「フォールディング」)
元の入力文字は、元の文字と必ずしも同じではなくても類似したターゲット・コード・ページの文字に置き換えられます。 場合によっては、特殊な Unicode コード・ポイントの複数の文字がデータベース・コード・ページ内の単一のコード・ポイント (ターゲット・コード・ページ内で相当する文字のうち最も近いもの) にマップされることがあるので、データベースへの挿入後にそれらの値の間の区別はなくなります。 このシナリオは、例 2 で例示されています。

以下の例は、UTF-8 エンコードのクライアントまたはアプリケーションを使用して非 Unicode データベース内の XML データを照会するときに、 生じる可能性のあるコード・ページ変換の影響を例示しています。 これらの例では、データベースがコード・ページ ISO8859-7 (ギリシャ語) を使用して作成されたと仮定しています。 XQuery 式を使用して、表 T1 に保管された XML データを突き合わせます。 保管された XML データは、Unicode のギリシャ語シグマ文字 (ΣG) および Unicode の数学シグマ文字 (ΣM) から構成されます。 コード・ポイント 0xD3 は、ISO8859-7 データベース内のシグマ文字を識別します。

以下のコマンドを使用して、表 T1 が作成されて値が取り込まれます。
CREATE TABLE T1 (DOCID BIGINT NOT NULL, XMLCOL XML);
INSERT INTO T1 VALUES (1, XMLPARSE(
       document '<?xml version="1.0" encoding="utf-8" ?> <Specialchars>
	<sigma>ΣG</sigma>
	<summation>ΣM</summation>
	</Specialchars>' 
       preserve whitespace));
例 1: 成功するコード・ページ変換 (文字がデータベース・コード・ページ内で表現可能)
XQUERY for $test in db2-fn:xmlcolumn("T1.XMLCOL")//*[. = "ΣG"] return $test
この式は、 目的の結果を生成します。
<sigma>ΣG</sigma>
この場合、 式 ΣG はクライアント側でギリシャ語のシグマ文字に対する Unicode コード・ポイント (U+03A3) として始まり、 ギリシャ語データベース・コード・ページ内のシグマ文字 (0xD3) に変換されてから、 XML 処理のための正しい Unicode 文字に戻されます。 ギリシャ語のシグマ文字はデータベース・コード・ページ内で表現可能なので、この式から正しいマッチが得られます。 この文字変換は、以下の表に示されています。
表 2. 文字データ変換 (例 1)
  クライアント (UTF-8)   データベース (ISO8859-7)   XML パーサー (UTF-8)
文字 U+03A3 (ギリシャ語シグマ) 0xD3 (ギリシャ語シグマ) U+03A3 (ギリシャ語シグマ)
例 2: 成功しないコード・ページ変換 (文字がデータベース・コード・ページで表現できない)
XQUERY for $test in db2-fn:xmlcolumn("T1.XMLCOL")//*[. = "ΣM"] return $test
この式は、 目的の結果を生成しません。
<sigma>ΣG</sigma>
この場合、式 ΣM はクライアント側で数学記号シグマに対する Unicode コード・ポイント (U+2211) として始まり、ギリシャ語データベース・コード・ページ内のシグマ文字 (0xD3) に変換されてから、XML 比較の実行時に ΣG 文字とマッチします。 戻り式の場合、プロセスは例 1 のプロセスと同じです。 Unicode XML 文字 σG は、最初にギリシャ語データベース・コード・ページ (ΣA) 内のシグマ文字に変換してから、クライアント UTF-8 コード・ページ (ΣG) 内のギリシャ語シグマ文字に変換し直します。 この文字変換は、以下の表に示されています。
表 3. 文字データ変換 (例 2)
  クライアント (UTF-8)   データベース (ISO8859-7)   XML パーサー (UTF-8)
文字 U+2211 (数学シグマ) 0xD3 (ギリシャ語シグマ) U+03A3 (ギリシャ語シグマ)
例 3: 文字エンティティー参照を使用してコード・ページ変換を迂回する
XQUERY for $test in db2-fn:xmlcolumn("T1.XMLCOL")//*[. = "&#2211;"] 
   return $test
この式は、 目的の結果を生成します。
<summation>ΣM</summation>
この場合、式 σM は、数学記号 sigma (U+2211) の Unicode コード・ポイントとしてクライアントで始まり、文字参照 &#2211としてエスケープされるため、Unicode コード・ポイントは XML パーサーに渡されるときに保持され、保管されている XML 値 ΣMとの比較が正常に行われます。 文字変換の迂回は、以下の表に示されています。
表 4. 文字データ変換 (例 3)
  クライアント (UTF-8)   データベース (ISO8859-7)   XML パーサー (UTF-8)
文字 U+2211 (数学シグマに対する文字参照) "&#2211" (数学シグマに対する文字参照) U+2211 (数学シグマ)
例 4: 成功しないコード・ページ変換 (文字がデータベース・コード・ページで表現できない)
この例は例 1 と似ていますが、異なる点として ASCII エンコード・データベースが使用されて、コード・ページのデフォルト置換文字が XML 式に導入されます。
XQUERY for $test in db2-fn:xmlcolumn("T1.XMLCOL")//*[. = "ΣG"] return $test
この照会は、 表 T1 内の正しい値との突き合わせに失敗します。 この場合、Unicode 文字 U+2211 (ギリシャ語シグマ) には ASCII コード・ページで一致するコード・ポイントがないため、デフォルトの置換文字 (この場合は疑問符 (?)) が導入されます。 この文字変換を以下の表に示します。
表 5. 文字データ変換 (例 4)
  クライアント (UTF-8)   データベース (ISO8859-1)   XML パーサー (UTF-8)
文字 U+2211 (数学シグマ) 0x003F ('?') 0x003F ('?')