【実務・中級編】ON ZERODIVIDEによるゼロ除算の例外ハンドリング – PL/Iの基本構文とデータ制御実践ガイド

ゼロ除算でシステムを止めないために―PL/IにおけるONユニットの「正しい」作法

現場の若い衆から、「バッチがU0000(システムアベンド)で落ちて、夜中の障害対応呼び出しが辛い」という泣き言をよく聞く。特に多いのが、メンテナンスされてきた古いプログラムにおける、予期せぬゼロ除算(ZERODIVIDE)だ。

メインフレームの世界では、一度の演算エラーが数百万件のトランザクションを止めるトリガーになる。今日は、PL/Iにおける`ON ZERODIVIDE`を使った、泥臭くも堅牢なエラーハンドリングについて、我々ベテランが現場でどうやってこの「爆弾」を処理しているか、その知見を共有しよう。

なぜ「ONユニット」なのか

PL/Iの強力な特徴の一つが、この例外処理機構だ。他言語のようにいちいち`IF divisor = 0 THEN…`と書くのも大切だが、計算ロジックが複雑化すると、どうしても抜け漏れが出る。

`ON ZERODIVIDE`を適切に定義しておけば、プログラム内のどこでゼロ除算が発生しようとも、制御をエラーハンドリングルーチンへ強制的に飛ばすことができる。システムアベンドを回避し、ログを残して「エラーレコードとして別ファイルへ退避させ、処理を継続する」という、基幹システムに求められる「止まらない処理」が可能になるわけだ。

実践的なエラーハンドリング構造

まずは、現場でそのまま使えるテンプレートを見てほしい。ポイントは、エラー発生時に「どこで」「どの値で」落ちたかを特定するための情報を確実に残すことだ。

/i
MAIN_PROC: PROCEDURE OPTIONS(MAIN);

/ — 宣言部 — /
DCL DIVIDEND FIXED DEC(15,2);
DCL DIVISOR FIXED DEC(15,2);
DCL RESULT FIXED DEC(15,2);
DCL ERR_MSG CHAR(80) VAR;

/ — ゼロ除算発生時のハンドラ設定 — /
ON ZERODIVIDE BEGIN;
/ エラーログを出力し、異常フラグを立てて処理を続行させる /
PUT SKIP LIST(‘ ゼロ除算エラー発生 ‘);
PUT SKIP LIST(‘被除数:’, DIVIDEND, ‘ 除数:’, DIVISOR);

/ ゼロ除算の結果を0として扱うか、またはエラー用フラグを立てる等の処理 /
RESULT = 0;

/ 必要に応じてシステムログやVSAMエラーログへ書き出す /
/ CALL WRITE_ERROR_LOG(DIVIDEND, DIVISOR); /

GOTO NEXT_RECORD; / 処理を中断せず、次のレコードへスキップする /
END;

/ — メイン処理ループ — /
DO WHILE (READ_SUCCESS);
GET FILE(IN_FILE) INTO(REC_DATA);

DIVIDEND = REC_DATA.VAL_A;
DIVISOR = REC_DATA.VAL_B;

/ ここでゼロ除算が発生すると、自動的に上のONユニットへ飛ぶ /
RESULT = DIVIDEND / DIVISOR;

WRITE FILE(OUT_FILE) FROM(RESULT);

NEXT_RECORD:; / GOTOの飛び先 /
END;

END MAIN_PROC;

現場で役立つデバッグのコツと注意点

1. GOTOによる制御フローの理解

上記の例では`GOTO`を使っているが、これはONユニット特有のテクニックだ。ONユニット内で`GOTO`を使い、プログラム内のラベルへジャンプすることで、例外が発生した行の直後をスキップし、処理を安全な地点まで復帰させることができる。これを「異常回復処理」と呼ぶ。

2. コンパイルオプションとエスカレーション

PL/Iのコンパイラオプションで`CHECK`や`SIZE`を有効にしている場合、例外処理が重なりすぎるとスタックを圧迫することがある。大規模なバッチでは、ONユニット内での処理は「最小限のログ出力と状態フラグの更新」に留めるのが鉄則だ。

3. VSAMアクセスとの併用

もしあなたがVSAMを読み込んでいる最中にこのエラーが発生した場合、単に`GOTO`で飛ばすだけでなく、必ず`UNLOCK`や`ENDFILE`の整合性を確認すること。エラーが起きた瞬間にファイルがオープン状態のままだと、後続のリカバリでJCLの再実行が困難になるからだ。

最後に:なぜ私たちが「堅牢さ」にこだわるのか

「エラーハンドリングを完璧に書く」というのは、単なるプログラミングのテクニックではない。これは、運用担当者への敬意であり、夜中に呼び出されるエンジニア(自分たちを含む)への自己防衛だ。

`ON ZERODIVIDE`を使いこなし、何が起きてもシステムが「優雅に」エラーを報告し、自律的に回復できる設計を目指してほしい。これが、我々メインフレーマーが守り続けてきた「信頼性」という名の言語化できない技術だ。

何か詰まったら、いつでも聞け。仕様書には載っていない「現場の泥臭い知恵」なら、いくらでも授けよう。

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