【実務・中級編】ON CONVERSION条件によるデータ型不一致の検知 – PL/Iの基本構文とデータ制御実践ガイド

現場で泣かないためのPL/I:ON CONVERSIONで「見えない爆弾」を検知せよ

メインフレームのバッチ処理において、最も胃が痛くなる瞬間の一つが、「データ変換エラーによるABEND」です。特に、VSAMファイルや固定長テキストから数値型へデータを転送する際、誰かがうっかり全角スペースやゴミデータを紛れ込ませると、プログラムは容赦なくS0C7(データ例外)を叩き出して沈没します。

今回は、IBMメインフレームの現場で生き抜くためのPL/I流「データ不整合検知術」、特に`ON CONVERSION`条件を使った堅牢なコーディング手法について語りましょう。

1. なぜCONVERSION条件を捕まえる必要があるのか

PL/Iの自動変換は非常に強力ですが、その分、入力データの「型」に対する甘えが許されてしまう側面があります。例えば、`PIC ‘999’`で定義した変数に、誤って英字やスペースが読み込まれた場合、デフォルトの挙動では即座にプログラムが異常終了します。

調査のためにダンプを解析する時間は、現場にとって最大のロスです。あらかじめ`ON CONVERSION`ユニットを仕込んでおけば、エラー発生時に「どのレコードの、どの項目が、どんな値だったのか」をログに吐き出し、スマートにジョブを終了(あるいはリカバリ)させることが可能になります。

2. 実践:ON CONVERSIONユニットの基本構造

以下は、バッチプログラムのメインプロシージャ内で、データ変換エラーを安全に捕捉する典型的な実装例です。

1
MAIN_PROC: PROCEDURE OPTIONS(MAIN);

/ — コンバージョンエラー時の処理を定義 — /
ON CONVERSION BEGIN;
PUT SKIP LIST(‘ データ変換エラーを検知しました ‘);
PUT SKIP LIST(‘エラー項目内容:’, ONCHAR);
PUT SKIP LIST(‘ソースコード上の発生箇所:’, ONLOC);
/ 必要に応じてここでフラグを立てて終了処理へ飛ばす /
STOP;
END;

DCL INPUT_RECORD CHAR(10);
DCL TARGET_NUM FIXED BIN(15);

/ わざと不正な値を代入してテスト /
INPUT_RECORD = ’12A4′;

/ ここで型変換が発生し、ON CONVERSIONが発火する /
TARGET_NUM = INPUT_RECORD;

PUT SKIP LIST(‘変換成功:’, TARGET_NUM);

END MAIN_PROC;

このコードのポイント

  • ONCHAR: エラーの原因となった文字そのものが格納される組み込み関数です。何が混入したのか一目瞭然です。
  • ONLOC: どのラベル(またはプロシージャ)でエラーが起きたかを教えてくれます。大規模なソースになればなるほど、この情報は救世主になります。
  • STOPの重要性: エラーを無視して処理を継続すると、予期せぬ後続処理でさらに大きな不整合を生むリスクがあります。現場では「安全な停止」を推奨します。

3. 実務での応用:VSAMアクセスと組み合わせる

実際の業務プログラムでは、VSAMのレコードを読み込む際にこの制御を適用します。特に、古いレイアウト定義と実際のデータの間で不一致がある場合、この手法は非常に強力です。

1
/ 読み込み処理のループ内で活用する例 /
DO WHILE (NOT_EOF);
READ FILE(VSAM_FILE) INTO(RECORD_AREA);

/ 特定の数値変換箇所をONユニットでガードする /
BEGIN;
ON CONVERSION BEGIN;
PUT SKIP LIST(‘レコードキーエラー:’, VSAM_KEY);
GO TO NEXT_RECORD; / 次のレコードへスキップして継続 /
END;

/ 変換ロジック /
WS_DATA = RECORD_FIELD;
END;

NEXT_RECORD: ;
END;

このように`BEGIN … END`ブロックで囲むことで、「変換エラーが発生したレコードだけをスキップし、処理を続行する」といった柔軟なエラーハンドリングが可能になります。

4. ベテランからのアドバイス:デバッグの極意

最後に、現場の先輩として一つだけ伝授しておきたいことがあります。

それは、「ON CONVERSIONに頼りすぎるな」ということです。

もちろん、エラーの検知には必須ですが、本来は「変換エラーが起きないようなインターフェース設計」が理想です。例えば、DB2のロード前チェックや、入力データの検証ルーチンを独立したサブルーチン(`VALIDATE_DATA`など)として作成し、変換前に`VERIFY`組み込み関数で数字かどうかをチェックする癖をつけてください。

1
/ 変換前の予防的チェック /
IF VERIFY(RECORD_FIELD, ‘0123456789’) ^= 0 THEN DO;
/ エラーログ出力処理 /
END;

`ON CONVERSION`は、いわば「最後の砦」です。これさえあれば、夜中の2時に「S0C7でジョブが落ちた!」という電話で叩き起こされる回数は、劇的に減るはずです。

メインフレームのコードは、時に無骨で古臭く見えるかもしれませんが、こうして堅牢に作り込まれたロジックは数十年経っても揺るぎません。皆さんのプログラムが、今日も安定して走り続けることを願っています。

それでは、また次回の技術談義で。

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