【PL/I実務】ON CONVERSIONでデータ汚染を「無害化」する:バッチ処理の堅牢性を高める鉄則
メインフレームのバッチ処理において、最も頭を抱えるのが「外部システムから届く謎の文字」だ。全銀フォーマットやレガシーな固定長ファイルにおいて、数値項目にスペースやアスタリスク、あるいはゴミデータが混入していることは珍しくない。
通常、PL/Iで文字型から数値型へ代入する際、無効な文字が含まれていれば即座に「CONVERSION」条件が発生し、プログラムは異常終了(ABEND U4038など)を迎える。しかし、24時間365日止まらない基幹システムにおいて、たった1レコードの桁ズレでバッチ全体を落とすわけにはいかない。
今回は、IBMメインフレームにおける「ON CONVERSION」を活用した、現場で使えるデータ変換エラーのハンドリング術を伝授する。
—
1. なぜ「ON CONVERSION」なのか
IF文で `VERIFY` 関数を使って毎回チェックすれば良い、という意見もあるだろう。だが、数百万件のレコードを処理する基幹バッチにおいて、すべての代入前に複雑なチェックコードを書くのは、メンテナンス性の観点からもパフォーマンスの観点からも賢明とは言えない。
`ON CONVERSION` ユニットは、プログラムの構造から切り離してエラー捕捉ロジックを定義できる。エラーが発生した瞬間に「変換処理の神様」が介入し、値を書き換えて処理を継続させるイメージだ。
2. 実践コード:無効値をデフォルト値へ置換する
以下のサンプルは、VSAMファイルから読み込んだ文字型データを、内部計算用のパック10進数(FIXED DECIMAL)へ変換する際の定石だ。
1
/ —————————————————————— /
/ PROCEDURE: CONVTEST /
/ 概要: 文字型から数値型への変換エラーを捕捉し、0で補完する /
/ —————————————————————— /
CONVTEST: PROCEDURE OPTIONS(MAIN);
DCL WS_INPUT_CHAR CHAR(5) INIT(’12A45′); / ここにゴミが入る想定 /
DCL WS_TARGET_NUM FIXED DEC(5,0);
DCL IS_CONV_ERROR BIT(1) INIT(‘0’B);
/ — ON CONVERSION ユニットの定義 — /
ON CONVERSION BEGIN;
/ 無効文字を0に置換して、処理を継続させる /
/ ONCHARで原因文字を、ONSOURCEで対象文字列を特定可能 /
WS_TARGET_NUM = 0;
IS_CONV_ERROR = ‘1’B;
PUT SKIP LIST(‘警告: 変換エラー発生。数値を0に補完します。’);
RESUME; / 変換処理の直後から再開させる /
END;
/ — メイン処理 — /
BEGIN;
/ ここで代入が発生し、エラーがあればONユニットへ飛ぶ /
WS_TARGET_NUM = WS_INPUT_CHAR;
IF IS_CONV_ERROR THEN
PUT SKIP LIST(‘処理継続: 異常値あり’);
ELSE
PUT SKIP LIST(‘正常処理: 値は ‘ || TRIM(WS_TARGET_NUM));
END;
END CONVTEST;
3. この設計における重要なポイント
- RESUMEの活用: `ON CONVERSION` 内で必ず `RESUME` ステートメントを使うこと。これがないと、エラー発生後に制御が戻らず処理がスタックするか、無限ループを引き起こす可能性がある。
- ONCHAR / ONSOURCE の活用: 上記例では単純化したが、実際の実務では `ONCHAR` を使って「どの文字が原因で落ちたか」をSYSPRINTに出力するログ設計を強く推奨する。原因特定が圧倒的に早くなる。
- スコープの意識: `ON` ユニットは記述されたブロック内、あるいは呼び出しスタック全体に影響を及ぼす。プログラム全体に適用したい場合はメインプロシージャの先頭に配置し、特定処理だけなら `BEGIN` ブロックで囲んで局所化するのが、バグを生まない秘訣だ。
4. ベテランからのアドバイス
「エラーを隠蔽して処理を継続する」ことは、時に諸刃の剣となる。本来システム管理者が検知すべき重大なデータ不整合を見逃すリスクがあるからだ。
現場で実装する際は、以下のポリシーを徹底してほしい:
1. ログには必ず残す: 変換エラーが発生したレコードのキー情報と、変換前の生データは必ずログに出力すること。
2. 統計を取る: プログラム終了時に「変換エラー発生件数」をカウンタで集計し、一定数を超えたら管理者にアラートを飛ばすような閾値制御を組み込むこと。
PL/Iは古い言語と言われるが、こうした例外処理の柔軟性は現代の高級言語にも引けを取らない。堅牢なシステムを構築するのは、こうした「泥臭い例外ハンドリング」の積み重ねだ。
次の改修案件では、ぜひこの `ON CONVERSION` を取り入れて、夜間バッチを朝まで止まらない強靭なものに仕上げてみてほしい。不明な点があれば、またいつでも聞いてくれ。
