XMLとDB2 for i 7.1との統合
DB2 for i 新機能を活用する
XML が組織間でのデータ交換、さらにソフトウェア・アプリケーション間でのデータ交換の事実上の業界標準となった点については議論するまでもないと思います。この事実を踏まえ、アプリケーション開発者には、これらのデータ交換から XML 値を保管し、処理できるソリューションが必要になります。
DB2 製品ファミリーの先例にならい、DB2 for i 7.1 リリースには、開発者による XML の保管および処理だけでなく、新しいデータ交換要件に備えた XML 値の生成を簡単に行うことができる新機能が組み込まれています。IBM i 7.1 における拡張 XML サポートの中核には、以下の 3 つの主要な構成要素があります。
- XML の保管と取り出しを簡単に行う新しい XML データ・タイプ
- アプリケーションが XML 文書内にカプセル化されたビジネス・データだけを抽出し、保管できるようにする XML 文書のアノーテーション付き分解
- 既存の DB2 for i データベース・オブジェクトから簡単に XML 値を生成する SQL XML パブリッシング関数
これらの機能のいくつかは、DB2 XML Extender 製品の経験がある開発者には聞き覚えがあることでしょう。IBM i 7.1 では ML Extender 製品がサポートされ、使用可能ですが、最終的に IBM は、その製品をこれら新しく統合された XML 機能と置き換えるつもりでいます。ということで前置きはこれくらいにして、これら新機能を使うことができるよう、詳しく見てゆきましょう。
XML文書の保管、取り出し、検証
XML データ・タイプは、DB2 for i 7.1 におけるすべての XML サポートのビルディング・ブロックです。図 1が示すように、XML 文書を保管する列を定義する場合は、この新しいタイプを使用できるのは明らかです。さらに、この XML データ・タイプは SQL ルーチンのパラメーター、HLL プログラムのホスト変数にも使用でき、配列およびグローバル変数を新たに SQL サポートするデータ・タイプとしても使用できます。組み込み SQL から JDBC に至るまで、新しい XML データ・タイプをサポートするために IBM はすべての SQL プログラミング・インターフェースへ機能拡張を行いました。対照的に、固有レコード・レベル入出力インターフェースには機能拡張は行われなかったため、XML 列から値を保管し、取り出す場合は SQL を使用する必要があるのです。
図 1 で見られる XML 列の例で 1 つ不思議な点として、resDoc 列定義に長さの値が指定されていない点があります。可変長列同様、DB2 for i は、単に保管されている XML 値のサイズに基づいてストレージを動的に割り振るだけです。DB2 XML タイプの最大サイズは 2GB です。XML 文書を XML 列内に保管する利点の 1 つとして、XML 文書すべてを通常のデータベース・バックアップ処理およびリカバリー処理でバックアップ、リストアできるようになる点があります。この例のように、列定義にコード化文字セット識別子 (CCSID: Coded Character Set Identifier) 値が指定されていない場合、DB2 は値 1208 を使用して XML データを UTF-8 エンコード方式で保管できます。DB2 が XML 値に対して構文解析操作や検証操作を行う場合、パフォーマンスの観点から UTF-8 をコード化スキームとしてお勧めします。
DB2 は、XMLPARSE 関数を明示的に指定しないすべての Insert および Update ステートメントの XML 入力値を暗黙的に構文解析します。この XML 構文解析処理は、列内に確実に整形式 XML 文書だけを保管するためにも必要です。図 2 の Insert ステートメントは、暗黙的および明示的両方の XML 構文解析を示しています。
DB2 では XML 文書の検証は決して自動的には行われません。開発者が、XML 検証が必要かどうかを判断します。この開発者による制御は 図 2 に示しています。ここでは、XML 文書はまず何も検証せずに挿入され、XMLVALIDATE 関数を組み込んだ 2 番目の Insert ステートメントで、挿入中の XML 値に対して検証するよう指定しています。検証は、プログラマーにより指定された XML スキーマ定義 (XSD: XML Schema Definition) を基にして行われています。XMLVALIDATE 関数の ACCORDING TO 節が、挿入中の XML 値を検証するのに DB2 がどの XML スキーマ定義を使用するか制御します。
XMLVALIDATE 関数と XMLPARSE 関数に加えて、これらの Insert ステートメントの例では GET_XML_FILE という別の新しい関数が使用されています。この関数は、XML 統合を簡単に行うために提供された統合ユーティリティーの 1 つです。図 3 にはこれらユーティリティーのリストが一式記載されています。GET_XML_FILE 関数により、開発者はファイル名を指定するだけで、すべてのデータ・リトリーブを DB2 に任せることで、ストリーム・ファイルまたはソース物理ファイルのメンバーに保管された XML に極めて簡単にアクセスして、使用できるようになります。
XML スキーマを検証に使用できるようにするには、XML スキーマを DB2 XML スキーマ・リポジトリー (XSR: XML Schema Repository) に登録および保管しておく必要があります。この前提条件もまた、統合 XML ユーティリティーを使用して行うことができます。図 4は、2 つのシステム・ストアード・プロシージャー XSR_REGISTER および XSR_COMPLETE を利用して登録している様子を示しています。
XSR_REGISTER プロシージャーの最初の 2 つのパラメーターは、それぞれ DB2 が XML スキーマを保管するライブラリー名とオブジェクト名を表しています。この場合、XML スキーマは MYLIB ライブラリーの RESSCHEMA というオブジェクトに保管されます。RESSCHEMA オブジェクトのオブジェクト・タイプは *SQLXSR になります。またこれら 2 つのパラメーターは、XMLVALIDATE 関数を使用して正しい XML スキーマ文書を使用するよう DB2 に指示する場合に開発者が必要とする、同じ識別子であるという点で重要です。第 4 パラメーターでは、実際の XML スキーマ文書が DB2 に渡されています。再度、便利な GET_XML_FILE 関数を使用して、XML スキーマを指定ファイルから取り出します。第 3 および第 5 パラメーターは、オプション・パラメーターであるため NULL 値に設定されています。オプション・パラメーターで実値が指定されるとは思いません。ご自分で判断するには "DB2 for i SQL Reference" (IBM i5/OS インフォメーション・センターの DB2 for i マニュアル・セクションで入手可能) を調べてください。
XSD の登録を完了するには XSR_COMPLETE プロシージャーを呼び出す必要があります。XSR_ADDSCHEMADOC プロシージャーを使用して複数の XML スキーマを 1 つの XSD に結合できるためです。最初の 2 つのパラメーターは明白なはずです。オプションの第 3 パラメーターには再度 NULL 値が渡されます。第 4 および最終パラメーターを使用して、XML 文書の検証または分解に登録された XML スキーマ定義を使用するかどうか DB2 に指示します。この XML スキーマ文書の目的は検証であるため、値 0 が渡されます。スキーマ文書を分解に使用する場合は、値 1 が渡されます。
検証済み XML データを保管するか未検証 XML データを保管するかどうかに関わらず、アプリケーションおよびレポートは、特定のビジネス値が入った XML 文書を素早く見つけることができなければなりません。IBM OmniFind Text Search Server はこうした高速テキスト検索機能を提供しています。IBM OmniFind サーバーの XML 検索機能の詳細については、私の記事 「Rev Up XML Searches with IBM OmniFind」 (2010 年 5 月、SystemiNetwork.com の記事 ID 64984) をお読みください。
XML 列からの値の取り出しはシンプルです。保管された XML 値はアプリケーションの文字変数に取り出したり、外部ファイルにコピーできます。外部ファイルにある XML データにより、保管 XML の別のサーバーへの FTP 送信および XML の Web サイトへの表示が簡単にできます。XML 列からデータを取り出す場合、XSLTRANSFORM 関数を使用して保管 XML を HTML 形式に変換できます。この関数により、XML を簡単に Web で使用できます。
XML データを外部ファイルにコピーする最も簡単な方法は XML ファイル参照変数です。ファイル参照変数は最初、文字ラージ・オブジェクト (CLOB) 値およびバイナリー・ラージ・オブジェクト (BLOB) 値の外部ファイルへのエクスポートをサポートするため導入され、XML サポートはその基盤に基づいて成り立っています。図 5 の例は、いかに努力しなくても保管された XML 値を外部ファイルにコピーできるかを示しています。XML ファイル参照変数を宣言した結果、コンパイラーはファイル参照変数から成る 4 つのフィールドを持った構造を生成します。最初に、MY_FILE ファイル参照変数の名前フィールドと名前長フィールドをそれぞれ、出力ファイル・パス ('/outdir/out1.xml') とそのファイル・パス値の文字長 (16) に設定しています。次に、ファイル操作フィールド (MY_FILE_FO) に定数値 (SQFCRT) が割り当てられ、指定した名前で出力ファイルを作成し、そのファイルにファイル参照変数に取り込んだ内容をデータとして追加するよう DB2 に指示します。最後に、SQL SELECT ステートメントまたは FETCH ステートメントを使用して XML 列 (resDoc) を XML ファイル参照変数にコピーします。
XML 文書のアノーテーション付き分解
XML 文書のアノーテーション付き分解は、XML 文書全体を保管しなければならない場合の代替案です。アノーテーション付き分解は確かに、未加工のビジネス値を XML 文書から抽出し、それらを DB2 列に保管するプロセスを説明する場合に聞こえがいい用語です。ストレージのスペースがもったいなくて XML タグのすべてを保管したがらない開発者は、この手法を選択できます。またこの判断は、監査要件により元の XML 文書を生成する必要があるかどうかによって異なります。これらは、XML 文書を保管するか、文書を分解するか判断しようとする場合に考慮すべき要因に過ぎません。
図 6 は、ハイレベルの分解プロセスを示しています。プログラマーは XML 文書を確認し、XML エレメントおよび属性を DB2 データベース内の列にマップします。開発者が正式に、アノーテーション付き XML スキーマ文書にこのマッピングを定義します。いったんマッピング定義が終わったら、図 4 に記載されたものとほぼ同一のプロシージャー呼び出しを使用して、XML スキーマ文書を DB2 XML スキーマ・リポジトリーに保管し、登録する必要があります。マッピングを定義すれば、アプリケーションは XDBDECOMPXML ストアード・プロシージャーを呼び出して、XML 文書を指定の DB2 列に分解するだけです。
図 7 には、図 8 でアノーテーション付き XML スキーマ文書を使用して分解されるサンプル XML 文書 (ship1.xml) が記載されています。アノーテーション付き XML スキーマに含まれているマッピングにより結果的に、1 つの行が Authors という表に挿入されており、2 つの行が Books 表に挿入されています。図 9 は、分解を行うために DB2 により生成された Insert ステートメントを示しています。
アノーテーション付きマッピング構文は圧倒的ではありますが、db2-xdb:rowset タグと db2-xdb:column タグに注目してください。これら 2 つのタグはそれぞれ、文書から指定された値を受け取るターゲット DB2 表および列を示します。例えば、name エレメントの値は Authors 表の同じ識別子 (Name) を持つ列にコピーされます。defaultSQLSchema エレメントは、Authors 表があるスキーマまたはライブラリーを指定します。この場合は、MYLIB です。defaultSQLSchema エレメントが指定されていない場合、非修飾表名は、指定の命名規則である SQL または System (*SYS) 命名のルールに従って解決されます。
author エレメントの ID 属性には、実質的に 2 つの異なる列がそのアノーテーション付きマッピングと関連付けられている点に注目してください。このマッピングにより、author ID 属性値を指定列の両方にコピーできるようになります。この機能は、XML を、親子関係を持つ表に分解する場合に便利です。2 つの表の間には共有鍵の値が必要になるためです。またアノーテーション・サポートは、プログラマーに XML 文書の値を無視する柔軟性を提供します。この例では、アノーテーション付きスキーマには、publisher エレメントへの参照は含まれていません。
DB2 XSR 内に保管および登録されたアノーテーション付き XML スキーマ文書により、実際の分解は XDBDECOMPXML ストアード・プロシージャーで行われます。図 9 にはこのプロシージャーのサンプル呼び出しが記載されています。最初の 2 つのパラメーターは、分解に使用するアノーテーション付き XML スキーマのライブラリーと名前を示しています。第 3 パラメーターは、分解する XML 値、最終パラメーターは単に NULL 値を渡す場合にお勧めする別のオプション・パラメーターです。この基本的な例で、アノーテーション付き分解サポートで何ができるか十分理解できたことと思います。アノーテーション付き構文の詳細については、IBM i5/OS インフォメーション・センターの DB2 for i マニュアル・セクションで入手できる SQL 資料をご覧ください。
SQL XML パブリッシング関数
SQL XML パブリッシング関数 (図 10) は DB2 for i 7.1 XML サポートの最後のピースです。これらのパブリッシング関数により、アプリケーションおよびクエリーは XML 値を簡単に生成できます。パブリッシング関数は、任意の列値または式を参照できます。例えば、これらの関数はグリーン・スクリーン・アプリケーションから入力されたデータを含む列を参照したり、分解された XML 文書からのデータを保管する列を参照できます。これらの SQL XML パブリッシング関数をアプリケーションでどのように活用できるか理解する最善の方法は、例をいくつか見てみることです。
図 11 の Select ステートメントは、XMLELEMENT 関数および XMLATTRIBUTES 関数を活用して、入社 25 周年を迎えた社員を表す 2 行の XML 出力 (図 12 は出力を示しています) を生成します。XMLELEMENT 関数の name パラメーターがはたして XML エレメント名を提供しています。この例の第 1 パラメーターは <employee> です。XMLELEMENT 関数の次の引数を使用して、それぞれ XMLNAMESPACES 関数と XMLATTRIBUTES 関数を使用して、生成された XML 文書の名前空間または属性を任意に提供できます。XMLATTRIBUTES 関数は <employee> エレメントの ID 属性値として empno 列を提供します。XMLELEMENT 関数の最後の引数は、エレメント値です。XML の性質として階層化されているという点を考えると、これは、この例の <Name> エレメントなどの実エレメント値またはネストされた XML エレメントが考えられます。
列値を参照する代わりに、<Name> エレメントの XMLELEMENT 関数は SQL 式の結果を取り込みます。この式は社員の氏名を間に空白を入れて連結してから、連結値を Name エレメントに提供します。<Extension> エレメントおよび <DeptNo> エレメントの残り 2 つの XMLELEMENT 呼び出しは一目瞭然です。XMLSERIALIZE 関数は XMLELEMENT 呼び出し全体をラッパーし、生成された XML 値をアプリケーションが取り込みやすく、5250 エミュレーターなどのテキストベースのインターフェースに表示できる文字列値に変換します。XML パブリッシング関数は、結合条件および選択条件も含む Select ステートメントの一部である点に注目してください。こうした柔軟性が備わっていることにより、開発者は最も複雑なクエリーに XML 生成機能を追加できるのです。
XML パブリッシングの出力例は、読みやすくするため手作業でフォーマットされている点に注意してください。SQL XML パブリッシング関数は、読みやすさを考えて空白文字や改行文字を追加することはありません。
生成された XML 値に XML エレメントのシーケンスまたは一連の XML エレメントが入っている場合、図 13 に示すように XMLFOREST 関数を使用して XML パブリッシング要求の構文を簡略化できます。前述の例の <Name>、<Extension>、および <DeptNo> の各エレメントの XMLELEMENT 関数呼び出しはすべて、XML エレメントのまったく同じシーケンスを生成する 1 つの XMLFOREST 呼び出しに結合されています。この XMLFOREST の例の結果は、前述の SQL XML パブリッシング例と同じ (図 12) になります。
図 12 の 2 つのパブリッシング関数の出力をもっと詳しく見てみると、生成された XML 値それぞれに単一行からの値しか含まれていないことがわかります。XML 値が複数行からのデータをカプセル化する必要があるという要件がある場合、開発者は XMLGROUP 集約関数および XMLAGG 集約関数を採用できます。これらの集約関数は、GROUP BY 節に似た処理を行います。実際、これらの XML 集約関数は図 14 に示すように、GROUP BY 節と組み合わせて使用できます。
この例では、XMLAGG 関数を使用して、パーツ型を属性として持つ <Parts> ルート・エレメント下にある指定されたパーツ型 (C01 および E21) 内のパーツをグループ化しています。外部 XMLELEMENT 関数を使用して、集約行の値をグループ化列、この場合は parttype 列からの値でラップしています。このルート <Parts> エレメントの下にネストされているのは、各パーツ型にすべてのパーツのパーツ識別子値を含んでいるすべての <pid> エレメントです。生成 <pid> エレメントは、各パーツ型内のパーツ順番でソートされています。図 15 では、XML 出力値が各パーツ・カテゴリー内のパーツ数とペアで記載されています。
簡単に XML 変換する
この記事では、DB2 の新しい XML 機能のほんのさわりをご紹介しました。それでも、これらの新機能を活用して XML データの処理、生成、保管について組織の要件を満たす方法の基礎知識が十分に得られたはずです。