QSAMでPDSメンバーにアクセスする

By 神居 - Posted: 2019/04/30 Last updated: 2019/05/01 - Leave a Comment

順次データセットは、QSAMを利用すれば論理レコード単位で簡単にアクセスできます。区分データセット用にはBPAMが提供されています。しかしながら、BPAMの場合はブロック(物理レコード)単位でないとアクセスできず、ブロックを論理レコードにバラしたり(あるいは論理レコードをまとめてブロックにまとめたり)バッファリングの制御なども自分でやらねばなりません。バッファリング制御はオプション処理的なものなので、やらなくてもアクセス自体はできます。しかし、ブロッキングとデブロッキングの処理は避けることができません。決して難しい処理ではありませんが、面倒であることは確かで、やらずに済むならそれに越したことはありません。
JCLでは、DSN=dsname(member)のようにデータセット名の後ろに()でメンバー名まで指定すれば、区分データセットのメンバーをQSAMでアクセスすることができます。これは、区分データセットのメンバー自体が、順次データセットと同じ構造を持っているからです。予めアクセスするメンバーが決まっているならJCL側の定義と組み合わせてQSAMでアクセスすることもできます。例えば、パラメーター・メンバーなどはその代表的なものの1つです。ところが、1つや2つのメンバーではなく、数十あるいは全部のメンバーに順番にアクセスしたい、となった場合はどうでしょうか?JCL側ではメンバー名まで定義できないことになります。そのような場合は、アクセスするメンバーを、JCLで定義する代わりに動的割り振り(DYNALLOC)でアロケーションしてQSAMでアクセス方法もあります。しかし、DYNALLOCは比較的オーバーヘッドが大きい処理なので、アクセスするメンバー数が多くなるとパフォーマンスの問題が出てきます。ISPFの起動プロシージャー内で、沢山のデータセットをALLOCコマンドで割り振っているとISPFが起動されるまでに時間が掛かることと同じです。
ここでは、メンバーをQSAMでアクセスでき、アロケーションのオーバーヘッドも掛からない方法として、JFCBを使用した区分データセットのオープン方法を紹介します。

このようなJCLで、SYSUT1 DDステートメントに定義された区分データセットの全メンバーを、SYSPRINT DDステートメントに定義されたデータセットへプリントするプログラムの例です。


DDステートメント定義情報の変更を行ってからデータセットをオープンする

JFCBを使用したデータセットのオープン処理を行うため、最初にJFCBを読み込みます。JFCBは、JCLのDDステートメントの定義情報だと考えればいいです。読み込んだJFCBには、JCLのDSNパラメーターで指定されたデータセット名は格納されていますが、メンバー名は当然ながら入っていません。メンバー名指定なしの区分データセットをQSAMでオープンすると、ディレクトリー部の先頭に位置付いてしまい、レコード形式などが不一致となるのでS013でABENDします。DSNパラメーターにメンバー名が入っていれば、オープンした時にそのメンバーの先頭に位置付けられてQSAMでアクセスができます。
従って、読み込んだJFCBのメンバー名フィールドにアクセスしたいメンバー名をセットすれば、JCL DDステートメントのDSNパラメーターに(メンバー名)まで指定したことと同じ状況を作り出せます。オープン前にJFCBを読み込み、その内容(JCL DDステートメント情報)を変更してからオープンすることもできます。

ポイントになる箇所は太字で示してあります。メンバー名はJFCBELEMフィールドに設定します。DDステートメントにDSN=dsname(member)と定義されると、JFCBのJFCBDSNMにdsnameが、JFCBELEMにmemberが格納されます。従って、オープン前にJFCBELEMにメンバー名を設定すれば、DDステートメントでメンバー名まで指定したことと同じになります。なお、オープン時に区分データセットのメンバー部に位置付けさせるためには、メンバー名の設定に加えて、JFCBIND1フィールドのJFCPDSフラグをオン(1)にする必要があります。JFCPDSフラグは1度オンにすれば、MVS(DFSMSdfp)側で変更されることはありません。
JFCBの準備ができたら、データセットをQSAMでオープンします。RDJFCBマクロで使用したDCBを指定してOPENマクロを発行します。この時、OPENマクロにTYPE=Jパラメーターを追加します。TYPE=Jは、JFCBがユーザー側で提供されたことを示します。TYPE=Jパラメーターを忘れると変更後のJFCBは反映されません。メンバーの読み込みならGETマクロ、メンバーの書き込みならPUTマクロを使用します。QSAMなので論理レコード単位でのアクセスです。1つのメンバーの処理を終えたら、データセット(メンバー)をクローズします。別のメンバーへの処理を行うのであれば、JFCBELEMに次のメンバー名を設定してオープンから繰り返します。
なお、メンバー内容を書き込みする場合、クローズ時にメンバー・ディレクトリーのユーザー・データ部分は消えてしまいます。ISPFエディターで保管したメンバーを、アプリケーション・プログラムのQSAMアクセスで書き直すような場合、メンバーのISPF統計データは消えてしまうことは知っておく必要があります。必要であれば、BLDLマクロなどでメンバー・ディレクトリーの情報を読み取っておき、後でBPAMでオープンし直してSTOWマクロで必要なユーザー・データを書き込む、などの処理を追加します。
※JFCBの読み込み方とRDJFCBマクロの使い方は、「DD文定義情報を得る(DEVTYPEとRDJFCB)」に解説してあります。


サンプル・プログラム(PDSPRINT)ソース・コード

PDS内メンバーのQSAMアクセスをセットアップした後、PDSデータセットのディレクトリー部をやはりQSAMでオープンします。
GETマクロでPDSディレクトリーブロックを1ブロック読み込み、その中に登録されているメンバーエントリーを取り出します。メンバー名をJFCBにセットしたら、PDSメンバーをオープンしてGETマクロで1レコード読み込み出力側のデータセットに書き出します。メンバーがEODになるまで処理を繰り返し、PDSメンバーをクローズします。
読み込み済みディレクトリーブロック内の次のメンバーエントリーに位置付けて、メンバー名をJFCBにセットする処理から繰り返します。ディレクトリーブロック内の全てのメンバーを処理し終えたら、次のディレクトリーブロックの読み込みから繰り返します。次に処理すべきメンバーエントリーのメンバー名がxFFFFFFFFFFFFFFFFであれば(これ以上メンバーがないことを示す)、PDSデータセットのディレクトリー部と出力側のデータセットをクローズしてプログラム処理を終了します。
※PDSディレクトリーの読み込み方は、「アセンブラーで区分データセットのディレクトリー部を読み込む」に解説してあります。

Posted in MVS実践アセンブラー・プログラミング • • Top Of Page