DB2 を XML でプログラムする、第 2 回: データベースでの XML サポートをアプリケーションのアーキテクチャーに活用する

IBM® DB2® 9 for Linux®, UNIX®, and Windows® の持つ、XML のストレージとクエリーのための新しい環境と、このシリーズの第 1 回で解説した XML データ・モデルとの関係を学びましょう。第 2 回では、このデータベースで改善された XML サポートをアプリケーションのアーキテクチャーに活用する方法に焦点を絞ります。

Hardeep Singh (hardeep@us.ibm.com), Architect Advanced Technologies, IBM 

Photo: Hardeep SinghHardeep Singh は Advanced Technologies Group のメンバーとして、DB2 XML ツールと XML マイグレーションのアーキテクトを務めています。彼の業界での経験は 23 年以上に及びます。



2007年 8月 02日

はじめに

データベースにおける XML の地位は、ここ 2、3 年の間に臨時雇いの労働者から第一級市民の地位へと変化しました。もはや、リレーショナルの世界に合わせるために XML の素性を変える必要はなくなりました。XML は、リレーショナル・データベースの世界の強力さと安定性を活用する一方で、その階層構造という財産を誇り高く維持しています。実際、リレーショナルの世界の隣人達の一部は、階層型の XML モデルの持つ表現力の豊かさを活用しようと、彼らを XML のように見せるための手法を採用してきました。

この記事は、XML のストレージとクエリーのための新しい環境が、第 1 回で解説した XML データ・モデルとどのように関係するかを説明します。まず、新しい XML ベースのアプリケーション開発アーキテクチャーを採用することによって、データベース・スキーマがずっと単純で、より自然になることを示します。また、データベースの中の XML データに対してクエリーを実行する方法が、アプリケーションの中のデータに対してクエリーを実行する方法と何も違わないことを説明します。そして最後に、リレーショナル・データと XML データを組み合わせることによって、両方の世界の最も良いところが得られることを示します。


XML データベースの基本

主なリレーショナル・データベースの大部分は何らかの形で XML をサポートしていますが、DB2 の pureXML™ サポートは、それらよりもはるかに堅牢で効率的です。そのため、XML プログラミング・モデルをテストするためのデータベースとしては理想的です。この記事では、このデータベースで改善された XML サポートをアプリケーションのアーキテクチャーに活用する方法に焦点を絞ります。

DB2 では、次のデータを保管し、照会し、操作し、公開することができます。

  • リレーショナル・データ: SQL
  • XML としてのリレーショナル・データ: SQL/XML
  • XML データ: XQuery
  • (リレーショナルと XML の) 混成データ: SQL/XML と XQuery
図 1. DB2 の混成保管
DB2 の混成保管

データベースに XML を保管する

リレーショナル・データベースで XML をサポートする主な利点は、リレーショナル・データと XML データの両方を同じテーブルに保管できることです。内部的には XML は階層構造の (ツリー) フォーマットで保管されますが、論理的にはデータベース・テーブルの中で (CLOB や BLOB のように) 1 つの列に保管されているように見えます。

第 1 回のデータ・オブジェクトから、2 つのテーブルがあること、そのそれぞれが少なくとも 2 つの列を持つことがわかります。

リスト 1. テーブル
CREATE TABLE CUSTOMER_TABLE (
CUSTOMERID CHARACTER (12) NOT NULL,
CUSTXML XML NOT NULL ,
CONSTRAINT CC1183665042494 PRIMARY KEY ( CUSTOMERID) )

CREATE TABLE PURCHASE_TABLE (
CUSTOMERID CHARACTER (12) NOT NULL ,
ITEMXML XML NOT NULL ,
CONSTRAINT CC1183665244645 FOREIGN KEY
(CUSTOMERID) REFERENCES CUSTOMER_TABLE (CUSTOMERID)
ON DELETE CASCADE ON UPDATE NO ACTION
ENFORCED ENABLE QUERY OPTIMIZATION )

上記のステートメントから、アプリケーションのデータ・オブジェクトを XML データとして保管することによって、リレーショナル・スキーマが大幅に簡略化されることが明らかです。それに加えて、インフラが相変わらずリレーショナルであるため、XML データはリレーショナル・データベースの持つ実証済みの機能 (トリガーや制約、外部キーの関係など) を活用することができます。

XML 列は論理的には VARCHAR 列や CLOB 列、BLOB 列などと同じように見えるため、INSERT 文もやはり似ています。

insert into CUSTOMER_TABLE values('hardeep',
'<Customer customerid="hardeep" firstname="hardeep" lastname="singh"/>')

あるいは、Java™ プログラムから挿入するのであれば、次のようになります。

リスト 2. Java プログラムから挿入する
String insertsql= "insert into PURCHASE_TABLE values(?,?)";
PreparedStatement iStmt=connection.prepareStatement(insertsql);
File inputfile= new File(filename); //filename is the path of the XML file
long filesize=inputfile.length();
BufferedReader in = new BufferedReader(new FileReader(inputfile));
iStmt.setCharacterStream(1,in,(int)filesize);
int rc= iStmt.executeUpdate();

混成ストレージをよく理解するために、リレーショナル・データベース内部で XML データが論理的にどう保管されているように見えるのかを調べてみましょう。

注意 : リレーショナル・データベースのベンダーによって XML 用の物理的なストレージ技術は異なるかもしれませんが、論理的なビューはどれも似ています。

図 2. DB2 の混成ストレージの論理的なビュー
DB2 の混成ストレージの論理的なビュー

XML にクエリーを実行する

データベースのスキーマ・モデルを展開すると、リレーショナル・テーブルとリレーショナル列を見ることができます。XML 列をさらに掘り下げると、スキーマはリレーショナル・モデルから XML 用の階層型モデルに変わります。さて、リレーショナル・スキーマと XML スキーマという 2 つのスキーマがあるという事実を乗り越え、単に両者を 1 つと見なすと、統一されたスキーマの中をより自然な形でナビゲートしてクエリーを実行できるようになります。

リスト 1 に示す統一されたスキーマで、CUSTOMER_TABLE の CUSTXML 列のデータを取得したい場合には、CUSTXML 列へのパスをクエリーのターゲットとして指定します。

SELECT CUSTXML FROM CUSTOMER_TABLE where customerid='hardeep';

これによって、CUSTXML 列の中にある hardeep 用の顧客データが返されます。

今度は、lastname が singh である顧客のデータが必要な場合を考えてみましょう。この場合には、各 XML 文書の lastname 属性へのパス (CUSTOMER_TABLE.CUSTXML/Customer/@lastname) を見つけ、それが singh かどうかをチェックする必要があります。

理想の世界であれば、そのクエリーは Select * from CUSTOMER_TABLE where CUSTXML/Customer/@lastname='singh' のようになるでしょう。しかし現実の世界では、これをデータベースのクエリー・エンジンが理解できる構文で表現する必要があります。XML 文書へのクエリーに使用できる、XQuery と呼ばれる新しい言語がデータベースの世界に導入されています。SQL は更新されており、この新しい言語を理解できる新しい関数が追加され、2 つの世界を橋渡しできるようになっています。そのため、姓 (last name) が singh の顧客を検索するクエリーは、今や次のようになります。

select CUSTXML from CUSTOMER_TABLE
where xmlexists ('$cust/Customer[@lastname= "singh" ]' passing CUSTXML AS "cust" )

あるいは、パラメーター化したクエリーを使った Java プログラムからこれを呼び出すとすると、次のようになります。

 select CUSTXML from CUSTOMER_TABLE
where xmlexists ('$cust/Customer[@lastname= $lname ]'
passing CUSTXML AS "cust" , cast(? as VARCHAR(12)) as "lname")

SQL/XML 関数にパラメーターを渡す、奇妙な構文に慣れさえすれば、リレーショナル・データと XML データに対する基本的な混成クエリーに対して、XML クエリーに含まれるものの大部分が XPath ステートメントであることに気が付くと思います。これは、XML データ・モデルの (第 1 回での) アプリケーション層で行ったことと非常に似ています。このアプリケーション層では、コードの大部分は DOM (Document Object Model) ラッパーに対して Xpath による呼び出しを行い、XML データに対してクエリーを実行したり、XML データを操作したりしていました)。

注意 : Viper 2 では、一部の SQL/XML 関数へのパラメーターの渡し方が少し単純化されており、例えば、先ほどのクエリーで、XMLExists を渡す節は CUSTXML 列を指定しません。

select CUSTXML from CUSTOMER_TABLE
where xmlexists ('$CUSTXML/Customer[@lastname= $lname ]'
passing cast(? as VARCHAR(12)) as "lname")

アプリケーション・ロジックをデータベースにプッシュする

XQuery は、大部分の高級言語の基本的な機能 (if-then-else、for、変数、関数、算術演算) をすべて持っています。そのため、クエリーの中にビジネス・ロジックを埋め込むことができます。また XQuery は XSLT にマッピングするための一般的な機能を数多く持っているため、XML に対してクエリーを実行できるだけではなく、XML 出力を直接データベースに書き込むこともできます。

例えば、第 1 回の XML データ・モデルの Customer の例を考えてみましょう。

<Customer customerid ="" firstname="" lastname="" >
<Items><Item ID="" description="" purchaseDate="" price="" /></Items>
</Customer>

アプリケーション・コードを DB2 クエリーで置き換える

アプリケーション層の 2 つのテーブルの XML データをマージする代わりに、同じことを 1 つの SQL/XML クエリーを使ってデータベースの中で行うことができます。つまり CUSTOMER_TABLE.CUSTXML/Customer/@customerid を 1 対多の関係で PURCHASE_TABLE.ITEMXML/Customer/@customerid に結合します。

図 3. 2 つの XML 列を結合する
2 つの XML 列を結合する
リスト 3. 2 つの XML 列にクエリーを実行する
values(xmlquery('

for $Customer in db2-fn:xmlcolumn( "CUSTOMER_TABLE.CUSTXML")/Customer

where $Customer/@customerid= $customerid

return
<Customer customerid ="{$Customer/@customerid}"
firstname ="{$Customer/@firstname}" lastname ="{$Customer/@lastname}" >{

for $Customer0 in db2-fn:xmlcolumn("PURCHASE_TABLE.ITEMXML")/Customer
where $Customer0/@customerid= $Customer/@customerid
return $Customer0/Item

}</Customer>

' passing cast( ? AS varchar(255) ) as "customerid" ))

hardeep という顧客が購入したすべての品目に対して作られる XML は、次のようになります。

図 4. クエリーの結果
クエリーの結果

上記のクエリーでは、外部 Customer 要素を作成し、CUSTXML 列のデータから属性を追加する必要がありました。DB2 Viper 2 (beta) は XML 文書を変更できる XQuery 更新式をサポートしているため、外部 Customer 要素を作成する必要はなく、代わりに customer テーブルの要素を使って purchase テーブルの項目を子として挿入することができます。

リスト 4. 2 つの XML 列に対する Viper 2 のクエリー
values(xmlquery('
				
for $Customer in db2-fn:xmlcolumn( "CUSTOMER_TABLE.CUSTXML")/Customer

let $items:=(<Items>{

for $Customer0 in db2-fn:xmlcolumn("PURCHASE_TABLE.ITEMXML")/Customer
where $Customer0/@customerid= $Customer/@customerid
return $Customer0/Item

}</Items>)

where $Customer/@customerid= $customerid

return
transform
copy $cust:=$Customer
modify(
do insert $items as last into $cust)
return $cust

' passing hardeep as "customerid" ))

上記のクエリーでは、データベースに保管された XML 文書の一部を検索し、取得し、マージしただけではなく、そうして得られた XML に新しい要素を追加することで、この XML を変換しました。また、hardeep が暗黙的に XML 型 (xs:string) にキャストされました。

データベース・クエリーと Java アプリケーション・コードとの比較

上記のクエリーを第 1 回の Java コード (Listing 6. Rewriting the application to use the XML model: リスト 6. XML モデルを使うようにアプリケーションを書き直す) と比較すると、ロジックが非常に似ていることに気が付きます。

  1. CUSTOMER_TABLE から Customer 情報を選択する。
  2. Items 要素を作成し、その顧客が購入したすべての品目を PURCHASE_TABLE から検索する。
  3. 選択されたリストの各品目を反復的に Items 要素に挿入する。
  4. Items 要素を Customer 要素に挿入する

ストアード・プロシージャーを作成する

データベースの中のビジネス・ロジックをアプリケーション・コードから分離するために、このクエリー用のストアード・プロシージャーを作成するのは適切なことです。

リスト 5. プロシージャーを作成する
CREATE PROCEDURE customerItems(IN custid varchar(12))
DYNAMIC RESULT SETS 1
LANGUAGE SQL
BEGIN
DECLARE c_cur CURSOR WITH RETURN FOR

values(xmlquery('

for $Customer in db2-fn:xmlcolumn( "CUSTOMER_TABLE.CUSTXML")/Customer

let $items:=(<Items>{

for $Customer0 in db2-fn:xmlcolumn("PURCHASE_TABLE.ITEMXML")/Customer
where $Customer0/@customerid= $Customer/@customerid
return $Customer0/Item

}</Items>)

where $Customer/@customerid= $customerid

return
transform
copy $cust:=$Customer
modify(
do insert $items as last into $cust)
return $cust

' passing custid as "customerid" ))
OPEN c_cur;
END

アプリケーション・コードをストアード・プロシージャー・コールで置き換える

これで、アプリケーション・コードは DB2 に対してストアード・プロシージャーを呼び出し、XML を DOM ラッパーに渡すようになりました。第 1 回でのXML モデルのアプリケーション・コード (リスト 6. XML モデルを使うようにアプリケーションを書き直す、の 2 行目から 8 行目) は、次のように簡単になります。

2. ResultSet dbResult = dbstmt.executeQuery("call customerItems ("+custid+")"
3. XMLParse customerXML = new XMLParse(dbResult. getString(1));

より複雑な例

今度は、各品目に対する保険も計算する、もう少し複雑なシナリオを考えてみましょう。少し難しくするために、保険は毎日変動するだけではなく、価格と共に変動することにします。これはつまり、customerid だけではなく、保険料率もクエリーに渡す必要があるということです。ここで、保険会社が提供している Web サービスに、毎日最新の保険料率を問い合わせるとしましょう。保険料率の情報は XML 文書として入手されます。

<insurance>
<rate price="100" currency="$" rate=".02"/>
<rate price="500" currency="$" rate=".018"/>
<rate price="" currency="$" rate=".015"/>
</insurance>

先ほどのストアード・プロシージャーを変更すると保険料率を計算することができます。

リスト 6. 各品目に対する保険も計算するストアード・プロシージャー
CREATE PROCEDURE customerItemsWithInsurance(IN custid varchar(12), rate XML)
DYNAMIC RESULT SETS 1
LANGUAGE SQL
BEGIN
DECLARE c_cur CURSOR WITH RETURN FOR

values(xmlquery('

for $Customer in db2-fn:xmlcolumn( "CUSTOMER_TABLE.CUSTXML")/Customer

let $items:=(
<Items>{
for $Customer0 in db2-fn:xmlcolumn("PURCHASE_TABLE.ITEMXML")/Customer

let $insurance:=<insurance currency="{($rate//rate[@price=""]/@currency)}">
{(
if($Customer0/Item/@price > 500) then (
$Customer0/Item/@price * $rate//rate[@price=""]/@rate
)
else (

if($Customer0/Item/@price > 100) then (
$Customer0/Item/@price * $rate//rate[@price="500"]/@rate
)
else (
$Customer0/Item/@price * $rate//rate[@price="100"]/@rate
)

)
)}</insurance>

where $Customer0/@customerid= $Customer/@customerid

return
transform
copy $item:=$Customer0/Item
modify( do insert $insurance as last into $item)
return $item
}</Items>
)

where $Customer/@customerid= $customerid

return
transform
copy $cust:=$Customer
modify(do insert $items as last into $cust)
return $cust

' passing custid as "customerid", rate as "rate" ));

OPEN c_cur;
END

ストアード・プロシージャーを呼び出す際には、customerid と保険料率を示す XML という、2 つのランタイム・パラメーターを使います。

call customerItemsWithInsurance(?,?)

上記の例から、データベースの中で操作されるデータが XML フォーマットであれば、XQuery の力を活用して、これまでのように SQL のみを使った場合よりも複雑なビジネス・ロジックの実装が可能になることが明らかです。また、クエリーに使用される XML がデータベースの中に存在する必要すらないことも明らかです。従って、SQL/XML クエリーに関与する XML データは、データベースの中に純粋な XML の形式 (階層構造形式) で保管することもでき、あるいは SQL/XML 関数を使って生成することもでき、さらにはランタイム・パラメーターとしてクエリーに渡すことすらできます。データベースとアプリケーション・サーバーとの区別が、次第に曖昧になるのです。


長所と短所

すべての新しい技術と同じく、この技術にも初期の頃に起こりがちな問題が出てくることでしょう。一部の問題は実装が最初のバージョンであることが原因であり、また別の問題は、正しくて実績があり、満足している方法から変更することが簡単ではないことによるものです。

  1. パフォーマンスは改善されつつありますが、まだリレーショナル・データに匹敵するレベルではありません
  2. XQuery は新しい言語であり、一部の SQL/XML 関数の構文は、慣れるまでしばらく時間がかかります。
  3. 既にリレーショナル・フォーマットになっているレガシー・データが大量にあります。
  4. 最も重要なことは、これはビジネス・アプリケーションとデータ・スキーマを作成するための新しい方法であり、オブジェクト指向ベースのアプリケーションと正規化されたリレーション・スキーマによる現在の方法とは異なるという事実です。
  5. こうした種類のクエリーのデバッグや最適化を行ってパフォーマンスを高められるツールは多くありません。

こうした問題点がある一方、新しいモデルの方がデータの扱い方が自然であるという利点があります。ビジネス・データ情報は、アプリケーション層とデータベース層の両方で (そして第 3 回で解説するようにクライアント層でも)、変更されずにそのまま維持され、操作されます。

  • データベースを取り巻く言語は異なる (Java、XQuery、JavaScript、PHP など) かもしれませんが、XML 文書をトラバースするために使われる言語 (XPath) は、どの層でも同じです。
  • レガシー・データはリレーショナルですが、Viper 2 で導入された新しい SQL/XML 関数を使うことで容易にクエリーを実行でき、XML に変更することができます。第 1 回の例「Case II -- all data stored in the database as relational (すべてのデータがリレーショナルとしてデータベースに保管された場合)」を見てください。このクエリーは、Viper 2 で導入された新しい XMLROW 関数を使えば、次のように単純化することができます。

    Select XMLROW (customerid, firstname, lastname OPTION as attributes ROW Customer)
    from customer_table where customerid=?

    また、リレーショナル・データと XML データの間を結合することもできます。このサンプル・シナリオとして、購入した品目の製品説明を含む第 3 のテーブルがあり、これがリレーショナル・テーブルだったとしましょう。品目の ID を使って結合を行えば、購入した各品目の製品説明を取得することができます。


    図 5. リレーショナル列と XML 列を結合する
    Joining relational and XML columns
    Select details, weight from SQLPRODUCT, ITEM_TABLE
    where xmlexists ('$itemxml/item[@itemid=$pid]'
    passing ITEM_TABLE.ITEMXML AS "itemxml", SQLPRODUCT.PID AS "pid" )

    DB2 9 では、SQL 文に埋め込まれた XQuery に passing 節を使ってランタイム・パラメーターを渡すことができますが、XQuery の中に埋め込まれた SQL には同じことをできませんでした。Viper 2 ではこの制限がなくなり、XQuery の中に埋め込まれたリレーショナル・クエリーにランタイム変数を渡すことができます。
    リスト 7. XQuery の中に埋め込まれた SQL にランタイム変数を渡す
    values(xmlquery('
    
    for $Customer0 in db2-fn:xmlcolumn("PURCHASE_TABLE.ITEMXML")/Customer
    where $Customer0/@customerid= $custid
    return (
    $Customer0/Item,
    db2-fn:sqlquery(
    ''select xmlrow(details, description, weight option ROW "description")
    from sqlproduct where pid= parameter(1)'', $Customer0/Item/@ID))
    
    ' passing cast( ? AS varchar(255) ) as "custid" ))

    従って、たとえ一部のデータがリレーショナル・テーブル内にあり、一部が XML 内にあったとしても、SQL クエリーあるいは XQuery の中から、あるいは両方の中から、XML データとリレーショナル・データの間を動的に結合できるようになりました。
  • パフォーマンスも、場合によっては大きな問題にならないかもしれません。その理由は次の通りです。
    • データベースに保管された XML 文書に対して、XPath 式ベースの索引を作成することができます。
      create index custfname on customer_table(info) generate key
      using xmlpattern '/Customer/@firstname' as sql varchar(64)
    • データベース・スキーマが単純になったため、必要な結合の数も少なくなっています。
    • クエリーの中のデータを、アプリケーションに送信する前に操作できるようになったため、I/O を削減できるかもしれません。
    • 鍵となる情報を、XMLTable などの SQL/XML 関数を使っていつでも XML 文書からリレーショナル列に抽出でき、それらに対してリレーショナル索引を作成することができます。
    • XML 文書に対してテキスト検索索引を作成することができます。

まとめ

XML は既に定着しています。大部分の業界や政府組織は彼らの XML スキーマを標準化しつつあり、これらのスキーマに準拠した電子文書を扱うように主張しつつあります。ネットワーク上で交換される B2B データは今や XML であるため、そのデータを、そのまま (pureXML で) データベースに保管した方が便利なはずです。いったんデータを XML として保管すれば、そのデータを XQuery と標準の SQL/XML を使って索引付けし、照会し、検証し、操作し、変換し、そして更新することができます。より多くのアプリケーション・ロジックをクエリーの中に入れることによって、データベースは中に保管されたストアード・プロシージャーを Web サービスやフィードとして公開でき、SOA (Service-Oriented Architecture) の世界に積極的に参加できるようになります。

「古き秩序はうつろい、新しき秩序へとすみやかに変わっていく」(Morte d'Arthur: 『アーサー王の死』より)

参考文献

学ぶために

  • ISV success with DB2 Viper」を読み、アプリケーションやルーチン、スクリプトを DB2 Viper に移行する準備を整えてください。
  • DB2 XML に関する技術記事一覧」で DB2 と XML に関する記事を見つけてください。
  • DB2 Viperの紹介」(developerWorks、2006年3月) を読み、XML データを管理するためのデータベース・オブジェクトの作成方法と、DB2 データベースに XML データを追加する方法を学んでください。
  • SQL を使った DB2 XML データの照会」(developerWorks、2006年3月) を読み、XML 列に保管されたデータに対して SQL と SQL/XML を使ってクエリーを実行する方法を学んでください。
  • Query DB2 XML data with XQuery」(developerWorks、2006年4月) を読み、XML 列に保管されたデータに対して XQuery を使ってクエリーを実行する方法を学んでください。
  • XML Programming with PHP and Ajax」を読み、サービス指向アーキテクチャーや他のビジネス・シナリオで DB2 9 の XML 機能を活用してください。
  • Use DB2 native XML with PHP」(developerWorks、2005年8月) を読み、DB2 Universal Database for Linux, UNIX, and Windows の次期バージョンで登場するネイティブ XML 機能を使うことで、アプリケーション・コードとリレーショナル・スキーマが単純化できることを学んでください。
  • Native XML Support in DB2 Universal Database」を読み、DB2 の新しい XML サポートを従来のリレーショナル・データベース技術と比較対照してください。
  • developerWorks Information Management ゾーンでは DB2 を詳しく学ぶことができます。このゾーンには、技術文書やハウツー記事、教育資料、ダウンロード、製品情報その他が豊富に用意されています。
  • developerWorks technical events and webcasts で最新情報を入手してください。

製品や技術を入手するために

  • DB2 Viper 2 open beta をダウンロードしてください。
  • 皆さんの次期開発プロジェクトを IBM trial software で構築してください。developerWorks から直接ダウンロードすることができます。

議論するために

コメント

developerWorks: サイン・イン

必須フィールドは(*)で示されます。


IBM ID が必要ですか?
IBM IDをお忘れですか?


パスワードをお忘れですか?
パスワードの変更

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


お客様が developerWorks に初めてサインインすると、お客様のプロフィールが作成されます。プロフィールで選択した情報(名前、国/地域や会社名)は公開され、投稿するコンテンツと一緒に表示されますが、いつでもこれらの情報を更新できます。

送信されたすべての情報は安全です。

ディスプレイ・ネームを選択してください



developerWorks に初めてサインインするとプロフィールが作成されますので、その際にディスプレイ・ネームを選択する必要があります。ディスプレイ・ネームは、お客様が developerWorks に投稿するコンテンツと一緒に表示されます。

ディスプレイ・ネームは、3文字から31文字の範囲で指定し、かつ developerWorks コミュニティーでユニークである必要があります。また、プライバシー上の理由でお客様の電子メール・アドレスは使用しないでください。

必須フィールドは(*)で示されます。

3文字から31文字の範囲で指定し

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


送信されたすべての情報は安全です。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=Information Management, XML, SOA and web services
ArticleID=276296
ArticleTitle=DB2 を XML でプログラムする、第 2 回: データベースでの XML サポートをアプリケーションのアーキテクチャーに活用する
publish-date=08022007