【入門編】EXEC CICS READ/WRITEコマンドとPL/I構造体のマッピング – PL/Iの基本構文とデータ制御実践ガイド

こんにちは!メインフレームの世界へようこそ。
JavaやCOBOLといった他の言語の経験がある方にとって、IBMメインフレームの世界、そしてそこで動く「PL/I(ピーエルアイ)」という言語は、どこか要塞のような、近寄りがたい雰囲気をまとって見えるかもしれません。

特に、画面やデータベースをオンラインで制御する「CICS(シーアイックス)」とPL/Iを組み合わせた開発現場では、「なんだか呪文のようなコードだな……」と戸惑うことも多いはずです。

でも、安心してくださいね。怖がる必要はまったくありません。今回は、CICS環境でのデータやり取りのキモとなる「EXEC CICSコマンドとPL/I構造体のマッピング」について、アライメントの罠も含めて、一つずつ優しく紐解いていきましょう。

1. なぜCICSとPL/Iの組み合わせで「構造体」が重要なのか?

Javaで開発をしているとき、データをやり取りするときは「オブジェクト」や「DTO(Data Transfer Object)」を使いますよね。COBOLであれば「01レベルのレコード定義」がそれに当たります。

PL/Iでも同様に、複数の異なるデータ型(文字や数値など)をまとめて一つの固まりとして扱うために「構造体(ストラクチャ)」を使います。

CICSオンライン画面から入力されたデータや、VSAMファイルから読み込んだデータを、PL/Iのプログラム内で綺麗に受け取るためには、CICSがメモリ上に展開するデータの並び順と、PL/Iの構造体のレイアウトを1ピクセル(1バイト)たりともズレずに一致させる必要があるのです。

もし、このマッピングがズレてしまうとどうなるでしょうか?
「名前が入るべき場所に、謎の数字が入り込む」「最悪の場合、メインフレーム特融の恐ろしいアベンド(強制終了)を引き起こす」なんてことになってしまいます。

2. JavaやCOBOL出身者がハマる、PL/I構造体の「奇妙な初期ルール」

PL/Iの変数名や構造体の宣言には、JavaやCOBOLとはちょっと違ったユニークなルールがあります。

実は、PL/Iには「厳格な予約語(ほかの用途に使えない単語)」がほとんどありません。
どういうことかと言うと、`READ` や `WRITE` といったCICSのコマンド名ですら、変数名として使おうと思えば使えてしまうのです(もちろん、混乱するのでやりませんが!)。コンテキスト(文脈)によって言語が賢く判断してくれるため、識別子の命名には非常に自由度が高いのが特徴です。

では、実際にCICSのレコードを受け取るためのPL/I構造体を見てみましょう。

1
/ =================================顧客マスターレコードの定義================= /
/ CICSのファイルから読み込んだ100バイトのレコードをすっぽり受け取る構造体です /
DCL 1 CUST_REC,
3 CUST_ID CHAR(5), / 顧客ID (5バイト) /
3 CUST_NAME CHAR(20), / 顧客名 (20バイト) /
3 CUST_STATUS CHAR(1), / ステータス区分 (1バイト) /
3 FILLER CHAR(74); / 残りのパディング領域 (74バイト) /

「あれ? COBOLの `01` とか `05` みたいな階層構造に似ているな」と思いましたか?その通りです!PL/Iでは `1` や `3` といったレベル番号を使って、データの親子関係を表現します。

ここで、JavaやCOBOLの感覚のままだと見落としがちな、PL/Iおよびメインフレーム特有の「最大の罠」についてお話しします。それがアライメント(境界調整)です。

3. 恐ろしい「アライメント」の罠と、BOUNDARYオプション

メインフレームのCPUは、数値を効率よく読み込むために、「4バイト境界」や「8バイト境界」といったメモリのキリの良い位置にデータを配置したがる習性があります。

例えば、もしあなたが以下のような構造体を宣言したとします。

1
/ アライメントの罠が潜む構造体の例 /
DCL 1 NG_STRUCT,
3 FLAG_A CHAR(1), / 1バイトの文字 /
3 NUM_B FIXED BIN(31); / 4バイトの数値(整数) /

「えっ、合計5バイトの構造体でしょ?」と思いますよね。
しかし、PL/Iコンパイラは親切心(のつもり)で、`NUM_B` を4バイトのキリの良いメモリ位置に配置しようとします。その結果、`FLAG_A` と `NUM_B` の間に、見えない「隙間(パディング・バイト)」を勝手に3バイトも差し込んでしまうのです!

CICSがファイルから読み込んできた生データは「隙間なしの5バイト」で届いているのに、PL/I側が勝手に「8バイト(1+3+4)」として解釈してしまったら……もうお分かりですね。データが盛大にズレて大パニックになります。

解決策:`UNALIGNED` を使おう!

この恐ろしい自動パディングを防ぎ、「CICSから届いたデータ通りに、1バイトの隙間も空けずにぴったり詰め込んでくれ!」とコンパイラにお願いする魔法のキーワードが `UNALIGNED`(アンアラインド) です。

実務のCICSプログラムでは、ストレージのマッピングを行う構造体には、必ずと言っていいほどこの属性を付与します。

1
/ ========================================================================= /
/ CICSストレージマッピング用の安全な構造体定義 /
/ ========================================================================= /
DCL 1 CICS_MAPPING_AREA UNALIGNED,
/ UNALIGNEDを指定することで、余計な隙間(パディング)を完全に排除します /

3 CICS_TRAN_ID CHAR(4), / トランザクションID (4バイト) /
3 CICS_TERM_ID CHAR(4), / 端末ID (4バイト) /
3 CICS_DATA_LEN FIXED BIN(15); / データ長 (2バイト:半精度整数) /

このように、`UNALIGNED` を指定しておけば、他の言語から移行してきた方でも、CICSのバイナリデータとPL/I変数をピタッと一致させることができます。

4. 実戦! EXEC CICS READ でのデータ受け渡し

それでは、ここまで学んだ構造体を使って、実際にCICSのファイルからデータを読み込むコードの全体像を見てみましょう。

1
MAPP_SAMPLE: PROC OPTIONS(MAIN);

/ 1. CICSから読み込むレコードの構造体定義(隙間なし!) /
Dcl 1 CUSTOMER_RECORD UNALIGNED,
3 01_CUST_NO CHAR(6), / 顧客番号 /
3 01_CUST_NAME CHAR(30), / 顧客名 /
3 01_CUST_BAL FIXED DEC(7,2);/ 預金残高(パック十進数:5バイト相当) /

/ 2. 処理に必要なその他の変数 /
Dcl W_CUST_NO CHAR(6) INIT(‘123456’);
Dcl EIBRESP FIXED BIN(31); / CICSレスポンスコード格納用 /

/ 3. EXEC CICS READ コマンドによるファイル読み込み /
EXEC CICS READ
DATASET(‘CUSTFILE’) / 読み込むCICSファイル名 /
INTO(CUSTOMER_RECORD) / 読み込んだデータを格納するPL/I構造体 /
RIDFLD(W_CUST_NO) / 検索キー(顧客番号) /
LENGTH(35) / レコード長(構造体の合計バイト数) /
RESP(EIBRESP); / 結果の応答コード /

/ 4. 応答結果の判定 /
If EIBRESP = DFHRESP(NORMAL) Then
Do;
/ 読み込み成功時の処理 /
/ ここで CUSTOMER_RECORD.01_CUST_NAME などを安全に参照できます /
End;
Else
Do;
/ エラー処理 /
End;

Return;
End MAPP_SAMPLE;

どうでしょうか?
`INTO(CUSTOMER_RECORD)` と指定するだけで、CICSのバッファにある生データが、私たちが定義した構造体の各フィールドへ魔法のように綺麗にマッピングされます。これがPL/IとCICSが長年築き上げてきた、レガシー基幹システムの強力な連携技です。

5. おわりに

今回は、CICS環境下におけるPL/I構造体のマッピングと、アライメントの注意点について解説しました。

  • レガシー特有の構造体宣言は、COBOLに似ていて親しみやすい。
  • しかし、CPUの境界調整による「見えない隙間(アライメント)」には注意が必要。
  • `UNALIGNED` を指定すれば、CICSとのデータやり取りも怖くない!

最初は見慣れない構文やルールに驚くかもしれませんが、基本の原則さえ押さえてしまえば、PL/Iは非常に直感的でパワフルな言語です。レガシーシステムの改修や移行調査も、一つひとつの仕様を紐解いていけば必ず理解できます。

あなたのメインフレームライフが、少しでも楽しく、安心なものになりますように。それではまた次回の技術解説でお会いしましょう!

タイトルとURLをコピーしました