ゼロ除算を「止まらないバッチ」に変える:PL/I ONユニットの現場的流儀
メインフレームのバッチ処理において、最も避けたい事態の一つが「データ異常によるabend(異常終了)」だ。特に深夜の基幹系バッチで、数百万件のレコードを処理している最中に`SOC7`や`S0CB`(ゼロ除算)でプログラムが落ちたときの絶望感は、経験した者にしか分からない。
PL/Iには、こうした危機を未然に防ぎ、処理を継続させるための強力な武器がある。それが`ON ZERODIVIDE`ユニットだ。今回は、単なるマニュアルの解説を超え、現場で「事故」を起こさないための実装パターンを伝授しよう。
—
1. ONユニットは「逃げ道」ではなく「制御フロー」である
PL/Iの`ON`ステートメントは、プログラムの実行中に特定の例外が発生した際、通常の制御フローを一時中断し、指定されたコードブロック(ONユニット)へ強制的にジャンプさせる仕組みだ。
ここで初心者が陥りやすい罠がある。それは「ONユニットを書きさえすれば安全」という過信だ。ONユニットを抜けた後、プログラムは「例外が発生したステートメントの直後」に戻る。つまり、ゼロ除算が発生した計算式をスキップして、次のロジックへ進むという挙動になることを理解しておく必要がある。
—
2. 実践コード:安全な数値演算の実装例
以下に、VSAMファイルから読み込んだ数値を演算し、万が一ゼロ除算が発生しても「0」として処理を継続する、現場でよく見かけるパターンのコードを提示する。
1
/ —————————————————————– /
/ PROCEDURE: CALC_SAMPLE /
/ 概要: VSAMレコードを読み込み、ゼロ除算を回避して演算する /
/ —————————————————————– /
CALC_SAMPLE: PROCEDURE OPTIONS(MAIN);
DCL INPUT_VAL FIXED DEC(9, 2); / 入力データ /
DCL DIVISOR FIXED DEC(9, 2); / 除数 /
DCL RESULT FIXED DEC(9, 2); / 計算結果 /
/ ON ZERODIVIDEユニットの定義 /
ON ZERODIVIDE BEGIN;
PUT SKIP LIST(‘警告: ゼロ除算が発生しました。結果を0で補完します。’);
RESULT = 0; / デフォルト値を設定 /
GOTO CONTINUE_PROCESS; / 計算処理をスキップして進む /
END;
/ (略) VSAMファイルのREADループなどを想定 /
DO WHILE(NOT_EOF);
/ 演算処理 /
RESULT = INPUT_VAL / DIVISOR;
CONTINUE_PROCESS:
/ 計算結果の出力処理など /
PUT SKIP LIST(‘RESULT:’, RESULT);
END;
END CALC_SAMPLE;
この実装のポイント
1. BEGINブロックの使用: `ON`ステートメントの後に`BEGIN; … END;`で囲むことで、複数の処理(メッセージ出力やログ記録など)を記述できる。
2. GOTOによる制御の回復: ゼロ除算が起きた計算式の直後にラベル(`CONTINUE_PROCESS`)を配置し、`GOTO`で飛ぶのが最も確実だ。これをしないと、計算結果が不定のまま後続処理が走り、論理バグを誘発する恐れがある。
3. BUILTIN関数の活用: 必要に応じて`DIVIDE`などの組み込み関数を活用し、精度制御を厳密に行うことも検討すべきだ。
—
3. 現場で生き残るための「鉄則」
私がこれまで数多くのマイグレーションやバッチ改修を見てきて、トラブル対応の現場で確信している「鉄則」を共有する。
- 例外の連鎖を避ける: `ON`ユニット内でさらに例外が発生するような複雑な処理は書かないこと。あくまで「リカバリ」に徹する。
- ログ出力は必須: ゼロ除算はデータ品質に問題がある証拠だ。`PUT SKIP LIST`だけでなく、システムログやエラーファイルに「どのキーのデータで発生したか」を必ず出力させること。後でデータ部門に突き返すための証拠が必要になる。
- ONユニットの有効範囲を意識する: `ON`ステートメントは、実行された位置からそのブロックの終了まで有効になる。もし、一部の計算のみを保護したい場合は、`REVERT`ステートメントを使用して、処理後に必ず元の状態に戻すのがプロの作法だ。
終わりに:技術は「何ができるか」ではなく「どう安全に運用するか」
PL/Iの古い仕様だからといって軽視してはいけない。この言語がこれほど長く基幹系で愛されている理由は、こうした「予期せぬ事態への堅牢な備え」が言語レベルで組み込まれているからだ。
新人や中堅エンジニアには、「プログラムが落ちないこと」だけでなく、「異常が発生した時に、誰が何をすべきか」をコード上で明確に表現することを意識してほしい。それができるエンジニアこそが、メインフレームの現場で長く信頼される存在になる。
もし現在、あなたの担当するバッチで頻繁に異常終了が起きているなら、まずはこの`ON ZERODIVIDE`からリファクタリングを始めてみてはいかがだろうか。
