2013.12.16
Carsten Flensburg著

データベースのジャーナル・エントリー・イメージの抽出

APIに関する例を使って説明する話題を探しているときに、すばらしいアイデアとスマートなテクニックを組み合わせることで、ある種の次元を加えることができます。System i 技術情報の「既成概念にとらわれずに SQL を考えてみる」の記事の中でジョン・ブライゼン氏はSQLを使用してジャーナル・エントリー・イメージからファイル・データを抽出する賢明な方法について説明しています。私は同氏の記事を読みましたが、このテクニックを使用する機会をまだ見出すことができていませんでした。そしてしばらくして、iPro Developer誌の読者であるアーサー・アダムス氏が、データベースのジャーナル・エントリー・イメージを抽出および回復して出力ファイルに追加することができるCLコマンドを実装する、というアイデアを私に提示してくれました。
ですから本稿ではExtract Journal Data (EXTJRNDTA)コマンドと、EXTJRNDTAコマンドがデータベース・ジャーナルの抽出を実行する際に役に立ついくつかのCLコマンドについて説明します。

ジャーナル・エントリーをオリジナルのフォーマットにマッピングする

賞賛されるべきはこれらの方法とアイデアをそれぞれ思いついたジョン・ブライゼン氏とアーサー・アダムス氏です。ジョンさんのSQLを使った精巧な方法は、データベース・ジャーナル・エントリーを2つのSQL文CREATE TABLEとALTER TABLEに基づいてオリジナルのファイル・レコード・フォーマットにマッピングし戻すというものです。

CREATE TABLE文を使用すると、一つ以上の既存のテーブルを指し示すSELECT文の結果であるテーブルを作成することができます。作成されたテーブルのレコード・フォーマットはSELECT文で指定したファイルのレコード・フォーマットを結合したものです。ここでDisplay Journal (DSPJRN)コマンドを実行し、コマンドの主要な選択パラメーターとして一つのデータベース・ファイルを指定してジャーナル・エントリーを出力ファイルに出力すると、その出力ファイルの構成は、ジャーナル・エントリーのメタデータを定義する複数の列を含んだジャーナル・エントリー・ヘッダー・セクションの後に、データベース・ファイルのレコードのイメージを保持しているJournal Entry Specific Data (JOESD)という名前の一つの列が続くという形になっています。
実行されるデータベース操作によって、後者の列は新しいレコードのレコード・データ、レコードの更新前後のレコード・データ、あるいは削除操作前のレコード・データのいずれかとなります。場合によってはジャーナル・エントリー・データのイメージをオリジナルのレコード・フォーマットにマッピングして、ファイル・フォーマットのデータに回復したい場合があります。たとえば、1年365日ロックされているファイルもありますからRemove Journaled Changes (RMVJRNCHG)を実行するという選択肢はありません。また、失敗したバッチ更新の回復があまりに複雑で、プログラムを使って回復してデータベースの整合性を保たなければならない場合もあります。あるいはファイルの更新を調査する必要があるため、更新データベース・レコードの更新前後の値を調べなければならない場合もあります。こうしたシナリオは、ジャーナル・エントリー・データのイメージをオリジナルのレコード・フォーマットにマッピングし戻すときに私が体験したもので、こうした状況ではEXTJRNDTAコマンドが有用であることがわかったのです。

RTVRCDLENコマンドとRTVTMPNAMコマンド

EXTJRNDTAコマンドは、Retrieve File Record Length (RTVRCDLEN)コマンドとRetrieve Temporary Name (RTVTMPNAM)という他の二つのCLコマンドを使っています。RTVRCDLENコマンドはデータベース・ファイルの全レコード長を取り出すもので、Retrieve Database File Description (QDBRTVFD) APIに依存していて、このAPIはデータベース・ファイルに関するあらゆる情報を取り出すことができます。

RTVTMPNAMコマンドはユニークな一時オブジェクト名を作成して返すもので、tmpnam()というCのライブラリ関数を使用しています。tmpnam()関数はIBM i上では2つのバージョンが実装されています。ネイティブのライブラリ版であるtmpnamはユニークなオブジェクト名をQTEMPライブラリ内に生成し、IFS版である_C_IFS_tmpnamはユニークなファイル名をrootファイルシステムの/tmpディレクトリ上に生成します。今回は、ネイティブ・ライブラリ版を使用してQTEMPライブラリ内にユニークなオブジェクト名を生成しています。そしてそのオブジェクト名はDSPJRNコマンドの出力ファイルに割り当てられ、抽出対象のジャーナル・エントリーを一時的に保持します。この処理全体をもう少し詳しく見てみましょう。

EXTJRNDTAコマンドの動作

EXTJRNDTAコマンド処理プログラムは以下のステップを実行してジャーナル・エントリーの選択を抽出し、指定された出力ファイルに追加します。

  1. DSPJRNコマンドで一覧されるジャーナル・エントリーに対する指定されたデータベース・ファイルのレコード長を抽出する。
  2. DSPJRN出力ファイル名に使用する一時オブジェクト名を抽出する。
  3. DSPJRNコマンドへ入力する際に使用するEXTJRNDTAコマンドのパラメーターをフォーマットする。
  4. DSPJRNコマンドを実行し選択されたジャーナル・エントリーを出力ファイルに追加する。
  5. オリジナルのデータベース・ファイルのレコード・フォーマットに追加したDSPJRN出力ファイル・フォーマットに基づいて、CREATE TABLEに対してRUNSQLコマンドを実行する。
  6. 以前「出口点、API、環境変数」で説明したように、ADDENVVAR SQL_VFY_ALTER_IGNOREコマンドを実行して SQLの照会メッセージCPA32B2を抑制する。
  7. RUNSQLコマンドであるALTER TABLE DROP COLUMN JOESDを実行してJOESD列を削除し、削除することでこの列をオリジナルのファイル・フィーマットのフィールドでオーバーレイする。
  8. RMVENVVAR SQL_VFY_ALTER_IGNOREコマンドを実行してSQL照会メッセージCPA32B2を再び有効にする。
  9. CPYFコマンドを実行して、上記ステップ4で作成したDSPJRN出力ファイルを上記ステップ5で作成した空のファイルにコピーする。
  10. 上記ステップ4で作成した一時ファイルを削除する。

これでEXTJRNDTA出力ファイルには選択されたジャーナル・エントリーがすべて含まれており、各エントリーはジャーナル・エントリーのヘッダー情報とその後にオリジナルのファイルのフィールドが続く構成になっています。完全にプロンプトされたEXTJRNDTAコマンドを図1に示します。図2図3はその他の2つのRTVTMPNAMコマンドとRTVRCDLENコマンドのコマンド・プロンプトをそれぞれ示していて、これらは本稿に関連するコードの中に含まれています。(SQL照会メッセージCPA32B2を抑制するには、解説記事「出口点、API、環境変数」に記載のコードをダウンロードしてインストールする必要があります)
EXTJRNDTA出力ファイルのヘッダー部分には図4に示すフィールドが含まれています。ジャーナルされたファイルのレコード・フォーマットを定義するフィールドと、変換されたジャーナル・エントリーから抽出したファイル・データを含むフィールドはJORESフィールドの直後に続いています。抽出したファイル・データをオリジナルのファイルに(あるいはオリジナルファイルのコピーに)戻すには、以下のCPYFコマンドを使用します。

記述1

このコマンドは、生成された出力ファイルJRNOUTから相対レコード番号4711をオリジナルのファイルORGFILEに加えています。
ここでもジョン・ブライゼン氏とアーサー・アダムス氏にこのEXTJRNDTAコマンドを思いつかせてもらったことについて感謝します。

ページトップ

ボタン