空の要素が存在するようなXMLからのデータの取得方法 For Oracle XML_DB

新年最初のXML_DBネタ…

はい、今回はOracle10.2から可能となったxmltable関数は基本的に使用しておらず、
Oracle9iのころから使用可能であるxmlsquenceを用いています。

そのなかで1つのXML文書中で、0〜n回出力可能な要素があった場合に、
その値と、XML文書中で1回出力される要素や属性を取得するという場合に下記のようにします。
つまりは、外部結合のような状態で値を取得したいみたいな場合です。

<会社情報>
<会社 ID="exbridge">
 <社名>株式会社エクスブリッジ</社名>
 <HP>http://exbridge.jp/</HP>
 <住所>
  <所在地 ID="本社">名古屋市名東区藤が丘</所在地>
  <所在地 ID="名古屋オフィス">名古屋市西区名駅2-26-11 名駅第十一平松ビル 6F</所在地>
 </住所>
 <採用情報>http://exbridge.jp/recruit.html</採用情報>
 <事業内容>
  <タイトル>情報システム受託開発
   <詳細>
    トリプルコストダウン戦略
      ・中国オフショア開発
      ・オープンソースソフトウェア
      ・コンポーネント指向
   </詳細>
  </タイトル>
  <タイトル>ソフトウェア開発・販売
   <詳細>
    ■事業部門向けソリューション
     AURORA 基幹.EAI ソリューション
     - 販売管理系
      見積,受注,売上,出荷モジュール
     - 購買管理系
      依頼,発注,仕入,入荷モジュール
     - 在庫管理系
      入庫,出庫,在庫モジュール
     ?必要なモジュールのみを選択
     ?モジュールを自由にカスタマイズ
     ?財務会計・EDIなどとの連動
   </詳細>
   <詳細>
    ■総務部門向けソリューション
     AURORA 総務.EAI ソリューション
     勤怠管理,備品管理,施設設備予約,
     経費精算,社内ファイル便,
     伝言管理,etc...
   </詳細>
   <詳細>
    ■経営陣向けソリューション
     OLAP/BIによる経営情報分析
     AURORA 基幹.EAIに蓄積された「売上」「仕入」データを分析するための仕組みを構築し、
     「顧客分析(CRM)」「商品分析(MD)」のノウハウを提供
     - OpenOLAP(オープンソース)
     - New WorkFRIEND(JBCC)
      ポータル(CMS)による知識経営
     CMSによる社内ポータル,コミュニティサイト構築を支援し、
     ナレッジマネージメントを成功に導きます
     得意先との知識・情報共有、社員間における
     知識・情報共有を効率的に実現し、ナレッジを
     有効に活用する経営を支援します
   </詳細>
  </タイトル>
  <タイトル>ITアウトソーシング</タイトル>
  <タイトル>IT投資コンサルティング</タイトル>
  <タイトル>BPRコンサルティング</タイトル>
  <タイトル>経営分析コンサルティング</タイトル>
 </事業内容>
 <提携企業>
  <社名 国="中国">南京日恒信息系統有限公司</社名>
  <社名 国="中国">偉伯庫魯信息技術(上海)有限公司</社名>
  <社名 国="中国">網元計算機系統有限公司</社名>
  <社名 国="中国">宇宙科学系統(天津)軟件開発有限公司</社名>
  <社名 国="中国">上海復旦微電子股紛有限公司</社名>
  <社名 国="中国">黒竜江国脈通信科学技術有限公司</社名>
  <社名 国="中国">杭州賽維軟件有限公司</社名>
  <社名 国="中国">済南泰楽信息技術有限公司</社名>
  <社名 国="中国">天津雷智信息技術有限公司</社名>
 </提携企業>
<会社 ID="exbridge">
</会社情報>

上記のXMLデータをOracleのXMLTable「会社情報XMLテーブル」へ格納してあるとします。

こんな時に、会社名と、事業内容の詳細にて表形式のデータが欲しい、詳細がなくても会社名はいるというときは…

select
extractvalue(value(compInfo), '/会社情報/会社/社名') as 会社名,
extractvalue(value(detail), '/詳細/text()') as 事業内容詳細
from
会社情報XMLテーブル compInfo,
table(xmlsequence(extract(value(compInfo), '/会社情報/会社/事業内容/タイトル/詳細'))(+) detail

上記SQLにて(+)がポイントです。

これにより、外部結合みたいな考えとして使用できるので、
<事業内容><タイトル><詳細>のノードがない場合でも、
会社名ノードでの一覧として取得できます。

(+)つけないと、<事業内容><タイトル><詳細>のノードが存在していない時には、
table(xmlsequence(extract(value(compInfo), '/会社情報/会社/事業内容/タイトル/詳細'))
は該当する情報がないということで、
NULLのものとの結合みたいな感じになって、
会社名すら取得できなくなってしまいます。

※宣伝かねさせていただいておりますので、XMLで日本語や全角スペース使ってます。
Oracleでちゃんと認識してくれるかはわかりませんのであしからず♪
あくまでもサンプルですので、そこはご理解ください。

ちょっとはしょって書いてるのでわかりにくいようでしたらごめんなさい(^_^;)

そんな方には「http://forums.oracle.com/forums/thread.jspa?messageID=1523858�」を…
まぁ英語ですが大体わかりますよ♪