DB2
Up one levelMAGIC + DB2 で XQuery(1)
ハイブリッドデータベースDB2 9(デービー・ツー・ナイン)
昨年の6月にアナウンスがあったとき、製品発表会に参加したんですね。確か「Viper Night」という洒落た名前のカクテルパーティだったと思うんだけど、今まで参加したことの無いような、ちょっとハイセンスな発表会だったのを覚えております。
その後、無料のハンズオンセミナーに参加させて頂きまして、その潜在能力の素晴らしさに驚かされました。他社データベースと比較した技術資料(その資料だけは配布されなかったんですが...)なんかはちょっとインパクトがありまして、かなり良いんじゃないかな?なんて思いました。(すぐ洗脳されやすいタイプなもので・・・。(^^;)
そんで、いつか自分もMAGICのアプリケーション開発の中でそれが使えるようになれば良いなぁ・・・と思っていたという次第です。
MAGIC V10でDB2の新機能は使えるか?
さて、問題となるのは、MAGIC V10のDB2ゲートウェイですが、「DB2 9」への対応は正式にはうたっていないと思います。
ですが、完全対応とまではいかないものの、そこそこに対応してくれたんじゃないでしょうか?細かいところで前よりも良くなっていますから・・・。
で、いろいろと試行錯誤してみたんですが、なんとかMAGICからも「XMLデータベースとして使えそうかな?」という見解が出ました。
DB2 9を、XMLデータベースとして使用するためには、最低でも次のような要件が必要になります。
- テーブル中に「XML」タイプのカラムを定義できること
- XQueryやSQL/XMLを使って検索処理を行うことができること
- 「XML」タイプのカラムへのアクセス
これらの詳細についてはまだ言及しませんが、順を追って説明させて頂きたいと思っています。
準備編
DB2 9のインストール
DB2 9は、開発者への無償版である「Express-C」を使用することが可能です。
Windows XPのProfessionalなら通常版でOKです。最近、VISTA用のモジュールがアップされた模様です。
IBMのWebサイト(http://www-06.ibm.com/jp/software/data/db2express-c/)からダウンロードが可能です。(ユーザ登録が必要です。)
ダウンロードしたセットアップ・プログラム(setup.exe)を実行し、インストールを実行します。
「セットアップ・ランチパッド」という画面が表示されますので、「製品のインストール」から「新規インストール」を選択して下さい。
途中、「インストール・タイプ」の選択画面が表示されますが、「標準」でOKです。
以後、殆ど初期値のままでインストールを進めてください。
DB2ゲートウェイのMAGIC V10への組み込み
MAGIC V10のインストール時にゲートウェイからDB2を選択します。
組み込むのを忘れて後から追加する場合は、セットアッププログラムを起動し、「変更」からモジュールを組み込んで下さい。
起動するMAGIC.INI の MAGIC_GATEWAYSセクションに下記の記述があることを確認しておきます。
[MAGIC_GATEWAYS]
MGDB18=Gateways\MGdb2.DLL
さて、ここまで準備はできたでしょうか?
次回は、実際に、データベースの作成などを行ってみたいと考えています。
MAGIC + DB2 で XQuery(2)
データベースとテーブルの作成
なんかもうすぐ春という季節になりましたが、如何お過ごしでしょうか?
今日は確定申告の締切日でしたが、医療費控除の申告をようやくすませて、家内共々ほっとしているところです。なんかこの2・3年、ギリギリの日に提出することが続いています・・・(^^;
さて、いきなり始まったDB2シリーズですが、今とあるシステムの試作にDB2 9を使って取り組んでいるんです。
結構、試行錯誤の連続なんですね。でも、こういう風にブログに書き込むと、頭の中が整理されて良いものです。
モノになるのかならないのかまだ分からないんですが、しばしお付き合い下さい。
では、今回は、テーブルを作るところからです。
データベースとテーブルの作成は、DB2の「コマンドウインドウ」(CLP-「コマンドラインプロセッサー」とも言う)を使って行い、その作成結果をMAGICの「定義取得」で行う手順について説明します。
「コマンドウインドウ」はいわゆる「DOS窓」みたいなものですが(実際にDOSコマンドが入力できます。)、コマンドラインの先頭に「DB2」を付加することによりDB2に対するコマンド命令を操作することが可能です。
- インスタンスの起動
インスタンスが起動していない場合は、「DB2START」コマンドによりそれを起動します。
DB2START
- データベースの作成
次のコマンドにより、「DB2XML」というデータベースを作成します。XMLタイプのカラムを使う場合は、コードセットをユニコードにします。
CREATE DATABASE DB2XML ON C USING CODESET UTF-8 TERRITORY JP
- データベースへの接続
作成したデータベースに接続します。DB2はログインしているユーザを認識するので、ユーザ名の指定は不要です。もし指定するなら、下記のコマンドの後に、「 user ユーザ名 using パスワード」を追加します。
CONNECT TO DB2XML
- テーブルの作成
次のコマンドにより、「XMLDBTEST」というテーブルを作成します。
CREATE TABLE DB2ADMIN.XMLDBTEST(DATAID CHAR(20) NOT NULL,
ここで、テーブル名の先頭に付加している「DB2ADMIN」は「スキーマ」と呼ばれるものです。データベースオブジェクトを論理的にグループ化するためのものですが、何もつけない場合は、ユーザー名が付加されますので、敢えて固定的なものを指定しておいたほうが良いと思います。
DATAXML XML,CONSTRAINT DATAID PRIMARY KEY(DATAID))
最初のカラムが「DATAID」という名前の文字タイプの項目です。二番目のカラムは「DATAXML」という名前の「XML」タイプ(DB2 9で新しく追加された型)の項目です。
最初の「DATAID」というカラムはインデックスも作成しておきます。 - データベースへの接続の終了
データベースへの接続を終了します。
CONNECT RESET
実際の実行画面は次のようになります。

今回は、コマンドウインドウで操作しましたが、「DB2CMD」という実行形式を使用し、テキストファイルにコマンドを書いて渡すことにより同様の処理が可能です。
MAGICからは、外部コール、「OSコマンド」で、表示を「M=最小化」や「H=なし」を選択すれば殆ど分からなくなります。
DB2CMD /c /w /i DB2 -f 処理ファイル -zログファイル
MAGICでの定義取得
MAGIC V10により、作成したテーブルを定義取得してみます。
- データベースの定義
MAGIC V10を起動し、データベースの定義を実行します。(オプション→設定→データベース)
DBMSに「DB2」を選択します。「DB名」には、作成したデータベース名「DB2XML」を設定します。(「DB名」には論理名も使用できるようです。)
- 定義取得
データリポジトリを開き、定義を追加します。
「データベース」には1で登録したDB2用のものを選択します。
名前に「XMLDBTEST」を入れます。
特性画面を開き(「Alt+Enter」)、「SQL」タブの「オーナ名」にテーブルを作成するときに指定したスキーマ名「DB2ADMIN」を入力します。(「オーナ名」にも論理名が使えるようです。)
最後に「定義取得」を実行します。(「オプション」→「定義取得」、もしくは「F9」キー)
しばらくすると処理が終了し、テーブルのカラムやインデックスが自動的に作成されます。
- カラム属性の修正
自動的に作成されたカラム「DATAXML」は若干の修正が必要です。
- 「型」を「A=文字」から「B=BLOB」に変更します。
- 特性画面のSQLタイプを「XML」にします。(必須でないかもしれません。)
- 特性画面のスタイルの「GUI表示形式」、「GUI表示形式テーブル」を「I=リッチエディット」等に変更します。(必須でないかもしれません。)
- テスト実行
変更内容を保存して実行(「Ctrl+G」キー)してみてください。
「DATAXML」カラムへは入力できませんが、「DATAID」に適当な文字を入力してみて、レコードの追加や削除ができればOKです。
MAGIC + DB2 で XQuery(3)
インポート・ユーティリティ
前回まででSQLデータベースに表ができたので、今回は実際にXMLファイルを取り込んでみます。
まず、テーブルにレコードを挿入する方法ですが、次の2通りの方法があります。
最初の方法は、SQL文の「insert」命令です。
insert into テーブル名 values(カラム1,カラム2,...,カラムN)
しかし、XMLタイプの項目の場合、その内容を全て記述してあげないといけないのでちょっと大変です。
(例えば、
'<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<Application>
<Header>
...略
</Application>'
のように・・・。)
もう一つの方法は「importユーティリティ」を使うものです。
こちらはファイルイメージのXMLファイルを、一括して取り込むことができるので、より便利な方法と言えるでしょう。
import from delファイル of del xml from XMLパス replace into テーブル名ここで、「delファイル」とあるのは、読み込みデータを記述した、いわゆるCSV形式ファイルです。このファイルは、各項目をカンマで区切って記述します。例えば、数値項目なら「100」、文字項目なら「"abc"」、XMLタイプの項目は、「"<xds fil='XMLファイル名' />"」のように記述します。
このとき「XMLファイル名」にはパス名をつけなくて良く、ファイルの格納されたパスは上記のコマンドラインの「XMLパス」で指定します。(「delファイル」も、「XMLパス」もコマンドを実行しているディレクトリからの相対パスでもOK)
「replace」は動作を表すオプションで、テーブル内のレコードは読み込む前に全てdropされます。残したまま追加読み込みさせたいなら「insert」を指定します。
インポート用delファイル書き出しプログラム
プロジェクトフォルダにデータ読み込み用の「inport_prg.del」というファイルを書き出すプログラムを作成してみます。
プログラムの一覧は、プロジェクトフォルダを自動的に検知し、メモリテーブルの「Progs.ProgNo」に作成されていますから、それをテキスト形式のファイルに書き出すだけです。
プログラムの作成手順を下記に示します。
- プログラムの追加
プログラムを追加して「delファイル出力」と名前をつけます。
タスク特性は「B=バッチ」に指定します。 - データビュー
メインソースは「4」の「Progs.ProgNo」を選択します。インデックスは何を選んでも構いませんが、表示順を見るために「2」の「ProgNo.」を選択します。
カラムには、「1」の「id」を追加します。
変数「出力イメージ」、文字タイプの書式「80」を追加します。代入に下記の式を追加します。プログラムのソースを表す「PRG」にidの5桁を加えたものを主項目にセットします。'"PRG'&Str(B,'5P0')&'","<xds fil=''Prg_'
&Trim(Str(B,'5'))&'.xml'' />"' - フォームの追加
クラス1の「T=テキスト形式」フォームを追加します。幅「80.000」、高さ「1.000」とし、変数「出力イメージ」を配置します。 - 入出力ファイルの定義
メディア:「F=ファイル」、アクセス:「W=書出」の名前「delファイル」を定義します。式には「'%Project%\inport_prg.del'」を指定します。 - ロジックの定義
レコード後処理に、フォーム出力を定義します。
「プログラム一覧」からの起動メニューを組み込む
ちょっと話題はズレますが、実は、前回ソース公開したプログラムには、プロジェクトフォルダを自由に選択できるような機能が組み込まれています。
#2のプログラム「プログラム一覧」を単独で実行して頂くと、コンテキスト・メニューの「プロジェクトフォルダの選択」から、任意のフォルダを選択することのできるダイアログを起動します。

更に蛇足ですが、このフォルダ選択プログラム(#8「プロジェクトの選択(A)」)では、V10になって新しく実装された関数「DirDlg」を使用しています。
DirDlg ('プロジェクトの選択','プロジェクトフォルダを選択して下さい.',C,0) 上記の式中、変数「C」には初期フォルダをセットしているのですが、前回ご紹介させて頂いた論理名「%WorkingDir%」を展開し、現在のプロジェクトフォルダを取得して初期値としています。さて、「プログラム一覧」のコンテキストメニューに、今回作成した「delファイル出力」を組み込んでみたいと思います。簡単な手順を示しておきます。
- メインプログラムへのイベント定義
メインプログラムを開き、イベントテーブル(「Ctrl+U」キー)に「delファイル出力」を追加します。 - メニューの修正
メニューリポジトリを開き、#3「プログラム一覧(有効プログラム)」と#4「プログラム一覧」にイベント「delファイル出力」を追加します。 - プログラム#2「プログラム一覧」の修正
プログラム#2「プログラム一覧」を開き、タスク「2.1」を開きます。
ロジックテーブルに、イベント「delファイル出力」を追加します。
追加したイベントにコールプログラム#9と、OSコマンド「'notepad '&Translate('%Project%\inport_prg.del')」の定義を追加します。 - プログラムの実行
プログラム#2「プログラム一覧」を実行します。
コンテキストメニューから「プロジェクトフォルダの選択」を起動し、任意のプロジェクトフォルダを選択してみて下さい。(リスト内容が切り替わると思います。)
更に、「delファイル出力」を実行します。メモ帳に出力されたdelファイルの内容が出力されます。
importユーティリティの実行
さていよいよXMLデータベース(DB2 9)へのXMLのインポートです。
とりあえず、今回もコマンドラインプロセッサーを使いましょう。
スタートメニューから「コマンド・ウインドウ」を起動します。
カレントディレクトリをリストを出力したプロジェクトフォルダに切り替え、下記のコマンドを入力してみて下さい。(大文字でも小文字でもOKです。)
IMPORT FROM INPORT_PRG.DEL OF DEL XML FROM SOURCE REPLACE
INTO DB2ADMIN.XMLDBTEST

このユーティリティですが、入力時には結構、厳しくXMLデータの内容のチェックをしているようで、XML中に使ってはいけないとされる半角カナなどの文字があると取り込みを拒否してしまいます。
(MAGICのソースはエラーとなるようなことはありません。)
また、大規模なXMLファイルを読み込むような場合は、いろいろと注意が必要です。
例えば、タグ内の文字列のサイズは最大で32000バイトです。これを超えるとこのタグの内容は検索することができなくなるので注意が必要です。複数のタグに分割する分にはOKです。
他にも大量のレコード(何万件)を読み込む場合は幾分の設定の変更が必要になります。
さて、読み込んだデータを確認してみましょう。
MAGICでテーブルをAPGで開いてもそれなりの確認はできますが、ここではDB2のGUIユーティリティ「コントロールセンター」を使ってみます。起動すると下記のような画面が表示されます。

オブジェクトビューから作成した表「XMLDBTEST」を表示します。
アクションから「オープン」すると内容の確認が可能です。

XMLの内容を見てみましょう。任意のレコードで「・・・」と書かれたボタンをクリックすると文書ビュアーが起動します。取り込まれたXMLドキュメントの内容の確認が可能です。

次回は、いよいよXMLデータベースの検索に挑戦です!
MAGIC + DB2 で XQuery(1)
Size
4322
-
File type
text/html
MAGIC + DB2 で XQuery(2)
Size
7147
-
File type
text/html
MAGIC V10解析(8)
Size
7011
-
File type
text/html
MAGIC + DB2 で XQuery(4)
SQL/XML
東京は桜も3分咲き程で、いよいよ春到来という感じですね。
「春眠暁を覚えず」と言われますが、まさにそのとおりで、朝起きるのが辛いこの頃です。
さて、前回まではXMLデータベースの作成手順まで説明してきました。いよいよ今回はXQueryを使った検索処理です。
XQueryとは、XMLデータベース用のクエリー言語のことを言います。SQLデータベース用のクエリー言語がSQLであるのと同様に考えると分かり易いかもしれません。
DB2 9は、XQueryをSQL言語でXMLを扱うための拡張仕様であるところの「SQL/XML標準」もサポートしており、これによってSQLからXQueryを実行することが可能です。
つまり、同じ行(レコード)上のXML型の列のデータに対しては、SQL/XML関数を使うことができ、従来のSQLデータについてはSQLでクエリー処理を行うことができます。これが他のリレーショナルデータベースやXML専用データベースと異なる大きな点です。
当然ながら、通常のカラムとXML型のカラムの両者を指定した複合的なクエリー処理を行うこともできるわけです。
MAGIC V10でDB2 9を使用する場合は、このSQL/XMLを利用します。
逆な言い方をすると、MAGICのいわゆる「SQLタイプ」のタスクで定義できるSQL文は、「SELECT文」(=SQL/XML)のみなので、この方法しかありません。例えば「FLWOR」形式を使用したxquery文等の処理ができるのかどうか試みたのですが、私が試した限りではエラーが出て使えませんでした。このあたりは、DB2のゲートウェイのバージョンアップに期待したいところです。
そう言えば、書き忘れていたのですが、データベース特性のオプションにある「開発モードでのテーブル変換」ですが、これはチェックを外しておいてください。XMLタイプのカラムがあると変換に失敗してしまうので、テーブルの定義を変更するときなどは、現状は別個に修正する必要があります。
SELECT文の実際・・・
例えば、コメントに「プログラム」 と記述されたプログラムの一覧を取得することを考えて見ましょう。コメントはプログラムにも、タスクにも、項目やフォームにもつけることが可能ですが、リポジトリ上は、「Comment」というタグの「val」属性に付きます。
プログラムやタスクではなく、例えば、あるイベントに付加されたコメントの場合はどうなるでしょうか? 答えは、「/Application/ProgramsRepository/Programs/Task/.../TaskLogic/LogicUnit/Comment」となります。
MAGIC V10では、いろいろな場所にコメントを付けられますが、いずれの場合も「Comment」という名前のタグで検索することが可能です。
どんな場所に付けられたコメントでも構わずに検索する場合は「/Application//Comment」と表すことが可能です。つまり「//」は間にどんなPATHが入ってもいいよという意味です。
SELECT文は次のようになります。
select c.DATAID from DB2ADMIN.XMLDBTEST c where
xmlexists('$i/Application[//Comment/@val[contains(.,"プログラム")]]'
passing c.DATAXML as "i")
ちょっと複雑に見えるかもしれませんが、構文はお馴染みのSELECT文「SELECT ... FROM ... WHERE ... ORDER BY ... 」です。
XMLEXISTS関数は、存在すればTrueを返すもので、WHERE句に使用することが可能です。
「//Comment」で階層下の任意のコメントを表すことはすでに書いたとおりですが、プログラムのコメントのみを対象とするなら「/ProgramsRepository/Programs/Task/Header/Comment」とします。
「[contains(.,"文字列")] 」は、「文字列」を含むという条件を意味します。
もし、上記の検索に「かつ、ルートタスクがバッチタスクのプログラム」という条件を加えるなら次のようになります。("[" と "]" の中でAND条件を加えます。)
select c.DATAID from DB2ADMIN.XMLDBTEST c where
xmlexists('$i/Application[//Comment/@val[contains(.,"プログラム")]
and /ProgramsRepository/Programs/Task/Header/TaskType/@val="B"]'
passing c.DATAXML as "i")
さて、今度は返るデータについてみてみましょう。
上の例では、該当レコードの「DATAID」カラムの一覧が返ります。
例えば、ここに「xmlquery」関数を使用することにより、該当するXMLノードの結果をXMLで返すことも可能です。例えば、次のような例です。
select c.DATAID, xmlquery('$i/Application/ProgramsRepository
/Programs/Task/Header' passing c.DATAXML as "i")
from DB2ADMIN.XMLDBTEST c where
xmlexists('$i/Application[//Comment/@val[contains(.,"プログラム")]]'
passing c.DATAXML as "i")
DATAIDに続いてカンマとxmlquery関数を使った項目が指定されています。
MAGIC V10でのコーディング
実際にV10でコーディングしてみます。
プログラムは2種類作ってみます。最初は、テスト用のプログラムです。
- プログラムの定義
「SQL/XMLサンプル1」というプログラムを追加します。(タスクタイプはオンライン) - データビューの定義
メインソースなしで、変数を3つ定義します。
- 「SQL文」
文字タイプ、書式512、代入で式「'select c.DATAID, xmlquery(''$i/Application/ProgramsRepository/Programs/Task/Header'' passing c.DATAXML as "i") from DB2ADMIN.XMLDBTEST c where xmlexists(''$i/Application[//Comment/@val[contains(.,"プログラム")]]'' passing c.DATAXML as "i")'」を定義します。 - 「出力XMLファイル」
文字タイプ、書式256、代入で式「'C:\V10HACKS.XML'」を定義します。 - 「データ有り」
論理タイプ、書式5
- 「SQL文」
- ロジックの定義
イベントテーブルに「処理実行」というユーザイベントを追加しておきます。
イベントハンドラを定義し、コールサブタスク
エラーで、'データが見つかりませんでした.'、条件は「NOT(データ有り)」 - フォームの定義
SQL文を編集できるように「複数行編集」可能なエディットコントロールを配置します。
ユーザイベント「処理実行」を実行するためのプッシュボタンを配置します。 - 子タスクの定義
ロジックでコールした子タスクを作成します。(タスクタイプは同じくオンライン) - データビューの定義(子タスク)
変数を3つ追加します。
- DATAID
文字タイプ、書式20、 - HEADER
BLOBタイプ - プログラムID
数値タイプ、書式5、代入に式「Val(Del(DATAID,1,3),'5')」

TABキーを押して表示されるダイアログに下記のものをセットします。
- データベースは「DB2XML」を選択します。
- 結果データベースは「Memory」を選択します。
- SQLコマンドには、「:1」を入力します。
- 入力パラメータには、親タスクの「SQL文」項目を指定します。
- 出力パラメータは、追加した変数のDATAIDとHEADERを定義します。
- DATAID
位置付けに変数「DATAID」を指定します。 - DATAXML
XMLデータの格納されたカラムをリンクしておきます。
- DATAID
- ロジックの定義(子タスク)
ユーザイベントを4つ(「ブラウザ(QUERY)」、「ブラウザ(DATAXML)」、「XML解読」、「タスク一覧」)追加しておきます。
タスク前処理に親タスクの変数「データ有り」を'FALSE'LOGで更新を定義します。
レコード前処理に親タスクの変数「データ有り」を'TRUE'LOGで更新を定義します。
イベント「ブラウザ(QUERY)」にアクション「Blb2File (HEADER,出力XMLファイル)」と、OSコマンド「出力XMLファイル)」を定義します。
イベント「ブラウザ(DATAXML)」にアクション「Blb2File (DATAXML,出力XMLファイル)」と、OSコマンド「出力XMLファイル)」を定義します。
イベント「XML解読」に、コールサブタスクを定義します。
イベント「タスク一覧」に、コールプログラム「タスク構造取得」を定義し、パラメータに「プログラムID」を指定します。更に、条件式「DbRecs ('5'DSOURCE,'')>0」なら、コールプログラム「タスク一覧表示」を定義します。 - フォームの定義(子タスク)
テーブルコントロールに、変数「DATAID」、「プログラムID」、「HEADER」、リンク項目「DATAXML」を配置します。更に定義したイベントを起動するためのプッシュボタンを配置します。 - 孫タスクの定義
取得したXML(HEADER)を解析する子タスクを追加します。
詳細な説明は省略しますが、データビューに定義した変数に、XMLGET関数を使用して、親タスクの変数「HEADER」に格納された情報から、プログラム名、タスクタイプ、更新日付、更新時刻などの値をそれぞれ取得し画面に表示します。
このとき、XPATHが、「/Header」で始まることに注目して下さい。
変数名 値の取得方法(代入する式の値) プログラム名 XMLGet (0,1,'/Header','Description') タスクタイプ XMLGet (0,1,'/Header/TaskType','val') 更新日付 Val(XMLGet (0,1,'/Header/LastModified','_date'),'10') 更新時刻 Val(XMLGet (0,1,'/Header/LastModified','_time'),'10')
プログラムの実行
作成したプログラムを実行してみましょう。
- プログラムの起動
起動すると、ダイアログにSQL/XMLのSELECT文が表示されます(編集も可能です)。
「SQLの実行」ボタンを押すと、DB2によるデータの検索が行われます。 - SQL/XML検索結果
画面の例では、2件のプログラムが検索されました。
DB2から返る値は、出力パラメータに指定した「DATAID」と「HEADER」ですが、プログラムのIDを判別し前回作成したタスク一覧プログラムを呼び出すことが可能です。また、BLOBに格納されたXMLデータは、いずれも「Blb2File」関数でXMLに出力することが可能です。(残念ながら、「File2Blb」関数を使って、XMLをXMLタイプのカラムに挿入することはできません。) - xmlquery関数で取得したXMLデータ
ブラウザにxmlquery関数で取得したXMLデータを表示させてみます。
指定したパス以下の部分的なXMLデータが出力されることが分かります。 - MAGICでの解析
DB2に格納されたXMLデータや、検索で取得したXMLデータは、MAGICのXML関連の関数によって任意のノードの値を取得することが可能です。BLOB項目を直接指定してXMLの値の取得が可能なので、不要なIOも発生しません。
ソース公開
例によって、今回も作成したプログラムのソースを公開しておきます。
MAGIC + DB2 で XQuery(1)
Size
4322
-
File type
text/html
MAGIC + DB2 で XQuery(2)
Size
7147
-
File type
text/html
MAGIC + DB2 で XQuery(3)
Size
10488
-
File type
text/html
V10HACKS_20070329.lzh
Size
95.6 kB
-
File type
application/x-lzh
MAGIC + DB2 で XQuery(5)
クロスリファレンスに挑戦!
前回は、SQL/XML機能を用いてMAGIC V10のプログラムリポジトリから任意の文字列検索を行ってみました。
今回は、プログラムのクロスリファレンス検索を行ってみようと思います。
クロスリファレンス機能は、オブジェクト(プログラム等)を参照している他のオブジェクト(プログラム等)を逆引きする機能ですが、MAGICの開発を行っている方にはお馴染みの機能かと思います。V9になってクロスリファレンスの結果が保存されるようになったので、とても便利になりましたよね。V10にも同様の機能が実装されています。
さて、このリファレンスを検索するにはどうすればいいでしょうか?
V10のプログラムとそのリポジトリファイルの内容を実際に見比べてみます。
まず、プログラム編集画面ですが、適当なプログラムを開き、ロジックの一部分でプログラムをコールしている箇所を探します。(下図は、「受注登録(Single)」プログラムのロジックタブの画面)

次に、このプログラムのリポジトリ(XMLファイル)の該当箇所をXMLのソースから探します。下記の部分が該当箇所になります。

このことから類推すると、あるプログラム(id=X)を参照しているプログラムの一群は、
子ノード「OperationType/@val」の値が"P"であり、
かつ、子ノード「TaskID/@comp」の値が"-1"で、
かつ、子ノード「TaskID/@obj」の値がXである
「CallTask」ノードを持つXMLドキュメント(プログラム)
を条件に探せば良いということになりそうです。
さて、上記の条件を xmlexists 関数に置き換えてみましょう。
前回公開させて頂いたプログラムソースの12番「SQL/XMLサンプル2」プログラムに今回のプログラムは作成済みです。該当箇所(ルートタスクの式4)は次のように記述してあります。
'select c.DATAID from DB2ADMIN.XMLDBTEST c where
xmlexists(''$i/Application//CallTask[OperationType/@val="P"
and TaskID/@comp="-1" and TaskID/@obj="'&Trim(Str(B,'5'))&'" ]''
passing c.DATAXML as "i")'
このSQL/XML文を実行することにより、コールしているプログラムを検索することが可能です。
簡単に、上記SELECT文の解説をしておきましょう。
まず、「/Application//CallTask」と間に「//」を入れることにより、任意の階層のタスクの「CallTask」ノードが該当するようになります。
「and」で連結する条件式は、"[" と "]" の間に記述するようにします。
「Trim(Str(B,'5'))」は、プログラムのidですが、これはパラメータで任意のプログラムのリファレンスを検索できるようにするためのものです。
「comp」属性は、コンポーネントを利用しているアプリケーションの場合は、そのコンポーネントの番号が記載されます。今回は、同じアプリケーション内のプログラム(-1の値が指定される)に限定して検索を行うことになります。(うまく処理できれば、コンポーネントを使用しているアプリケーション間のクロスリファレンスの取得も可能かもしれませんね!)
さて、いよいよ、プログラムを実行してみましょう。
クロスリファレンスの実行
今回作成したプログラムは、#2:「プログラム一覧」を実行し、プログラムを一覧表示させたときのポップアップメニューから実行できるようにしてあります。
XMLファイル(プログラムのリポジトリ)をインポートしたプロジェクトを選択し、プログラムの一覧を表示します。
任意のプログラム(画面上は、「受注書印刷 BTCH」)をクリックし、マウスの右ボタンから、「SQLテスト2」を選択します。
するとどうでしょうか?検索が終わり、下記のようにプログラムを参照しているプログラムの一覧が表示されます。
試しに、MAGIC V10のクロスリファレンスを実行し、結果が正しいかどうか確認してみましょう。

検索処理速度の比較・・・
さて、実際の検索スピードはどれくらい違うのでしょうか?
今回のプログラムは、プログラム単位に「あるかないか」を探すだけなので、V10のクロスリファレンス機能のようにプログラム内の該当箇所までを探すものではありません。
それを承知の上で、単純に結果が出てくるまでの時間を、比較してみたのが次の表です。
(プログラム本数200本程度のアプリケーションで試しました。)
| 処理内容 | MAGIC V10のクロスリファレンス検索 (プログラムのみ) |
DB2 9によるsql/xml検索 |
|---|---|---|
| リポジトリのDB2へのインポート | ー | 30秒 |
| プログラムの検索処理時間 | 20秒 | 4秒 |
さて、如何でしょう?
百聞は一見にしかずではありませんが、実際に試されてみることをお勧めします。 「これがXMLデータベースというものか!」というようなちょっとした感動があります...。
高々200行程度のデータベースでも高速に検索してくれますから、大規模なアプリケーションになればなるほど、更に効果が現れるように思います。
これならリアルタイムでの検索を行わせるようなプログラムを作ったとしても、殆ど実用レベルで動作可能ではないでしょうか?
今回は小規模のデータだったので、索引は作成していませんが、大規模のデータベースになる場合はXMLドキュメントに索引を作成することも可能です。(このあたりはまたの機会に・・・。)
