【実務・中級編】ON ENDFILEユニットによるストリーム入出力の終了制御 – PL/Iの基本構文とデータ制御実践ガイド

【PL/I深掘り】ON ENDFILEでハマらないための「終了処理」の鉄則

メインフレームの現場でPL/Iを触っていると、必ず直面するのが「ストリーム入出力の制御」だ。特にバッチ処理の定番である「ファイル読み込み終了時(ENDFILE条件)のハンドリング」は、シンプルに見えて、実は仕様の勘違いが致命的なループや予期せぬ異常終了を招く温床になる。

今回は、我々エンジニアが保守現場で「なぜかループが抜けない」「終了処理が正しく走らない」と頭を抱えるポイントを整理し、堅牢なコードの書き方を伝授しよう。

1. ON ENDFILEの基本と「復帰」の考え方

PL/Iの`ON ENDFILE(ファイル名)`は、単なる終了通知ではない。これは「条件が発生したときに実行される割り込みルーチン」だ。

ここでの最大の落とし穴は、「ONユニットを抜けた後、制御がどこに戻るか」という点にある。基本仕様では、ONユニットの処理が終わると、条件が発生した直後の文(GET文など)の「次の文」に戻ろうとする。だが、ENDFILEが発生した地点で、ファイルは既にEOFに達している。そのまま何も考えずに処理を続行しようとすれば、再びENDFILEを検知し、無限ループに陥るのは火を見るよりも明らかだ。

現場の定石としては、ONユニット内で`GO TO`を使ってループの外へ脱出するか、フラグを立ててメインループ側で制御するのが鉄則だ。

2. 実践的なコーディング例

以下に、VSAMやQSAMを扱うバッチ処理で最も安全と言える、フラグ制御を用いた実装パターンを示す。

/i
/——————————————————————-/
/ プログラム名: BATCH01 (メインバッチ処理) /
/ 目的: 入力ファイルを読み込み、終了判定を確実に行う /
/——————————————————————-/
BATCH01: PROCEDURE OPTIONS(MAIN);

DCL INFILE FILE RECORD INPUT; / 入力ファイル定義 /
DCL EOF_FLAG BIT(1) INIT(‘0’B); / 終了判定フラグ /

/ 1. ONユニットの定義:ファイル終了時の挙動を指定 /
ON ENDFILE(INFILE) BEGIN;
EOF_FLAG = ‘1’B; / 終了フラグを立てる /
END;

OPEN FILE(INFILE);

/ 2. メインループ:フラグを監視する /
DO WHILE (EOF_FLAG = ‘0’B);
READ FILE(INFILE) INTO(REC_BUFFER);

/ EOF検知後の再読み込みを防ぐためのガード /
IF EOF_FLAG THEN LEAVE;

/ ここにビジネスロジックを記述 /
CALL PROCESS_DATA(REC_BUFFER);
END;

CLOSE FILE(INFILE);
PUT SKIP LIST(‘BATCH PROCESSING COMPLETED SUCCESSFULLY.’);

END BATCH01;

このコードのポイント

  • `EOF_FLAG`による制御: `GO TO`での強引な脱出は、スパゲッティコードの元だ。フラグ管理にすることで、処理の終了ポイントが明確になる。
  • `LEAVE`の活用: EOFを検知した直後に、ループの残りの処理をスキップして即座に抜ける。これが一番安全だ。
  • `RECORD`入出力の意識: ストリーム入出力(`GET`)ではなく、`READ`を使用している点に注目してほしい。基幹系ではデータの整合性が命であり、レコード単位での制御が推奨される。

3. ベテランからのアドバイス:トラブルを避けるために

現場で調査をしていると、`ON ENDFILE`の記述場所が分散しているコードをよく見かける。これらは、保守時に「どのONユニットが有効なのか」を追うのが非常に困難だ。

覚えておくべき3つの掟

1. ONユニットはPROCEDUREの最初の方で宣言せよ
ONユニットは動的だ。呼び出された手続きのスコープ内で定義されるため、宣言場所が不明確だと、意図しない場所で古いONユニットが有効になり、バグの温床となる。
2. `FINISH`条件との併用を検討せよ
ファイルのClose漏れを防ぐなら、`ON FINISH`を使用して、プログラムが正常終了・異常終了にかかわらず、開いているファイルがあればCloseするように組むのがプロの仕事だ。
3. `BUILTIN`関数を侮るな
ファイルの現在状況を確認したい場合は、`STATUS(INFILE)`などの組み込み関数を活用しよう。特にVSAMアクセス時は、`ON CODE`関数で発生した例外コードを確認することで、単なるEOFなのか、それとも物理的なI/Oエラーなのかを即座に切り分けられる。

まとめ

PL/IのONユニットは、使いこなせば非常に強力なエラーハンドリングツールになる。しかし、それは「制御フローを書き換える」という強力な武器であることを忘れてはならない。

今日紹介したようなフラグ制御と確実なループ離脱を徹底するだけで、バッチ処理の安定性は格段に向上するはずだ。次の改修時、ぜひ自分のコードを見直してみてほしい。「このループ、本当に安全に抜けられているか?」と。

メインフレームのコードは、先人が残した資産であり、我々の手でそれをより堅牢に磨き上げていくのが責務だ。また何かあればいつでも聞いてくれ。

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