【テクニカル・上級編】ON CONVERSION条件によるデータ変換エラーの捕捉 – PL/Iの基本構文とデータ制御実践ガイド

予約語なき言語の深淵:PL/Iにおけるデータ変換とON CONVERSIONの真実

メインフレームの現場で、PL/Iのコードを眺めているとふと思うことがある。「なぜ、この言語はこれほどまでに自由で、そして残酷なのか」と。

CやJavaに慣れたエンジニアがPL/Iのソースコードを初めて見たとき、最も困惑するのは「予約語が存在しない」という設計思想だろう。`IF`や`THEN`さえも、実は変数名として定義できてしまう。この自由度は、コンパイラのパーサにとっても、我々アーキテクチャ設計者にとっても、諸刃の剣だ。

今日は、その自由度がもたらす「数値変換の罠」と、それを制御する`ON CONVERSION`による防衛的プログラミングの深部について掘り下げたい。

数値変換という「見えない爆弾」

バッチ処理において、外部から供給されるCSVやフラットファイルが、予期せぬゴミ(空白、英字、あるいは制御文字)を含んでいることは珍しくない。特に、`DECIMAL FIXED`(いわゆるパックデシマル)の演算領域へ、文字データを代入しようとした瞬間、システムは悲鳴を上げる。

1
DCL INPUT_CHAR CHAR(10) INIT(‘123A5’);
DCL TARGET_DEC FIXED DEC(5,0);

/ ここでコンバージョンエラーが発生し、デフォルトではS0C7等のABENDへ直行する /
TARGET_DEC = INPUT_CHAR;

多くの開発者は、ここで`ONCODE`や`ONCHAR`の存在を忘れるか、あるいは安易にプログラムを落としてしまう。しかし、基幹システムの保守を担うテックリードとしては、この「変換失敗」を捕捉し、業務的に正しいハンドリングへ昇華させることが求められる。

ON CONVERSIONによる賢明なハンドリング

`ON CONVERSION`条件は、まさにこの瞬間のためのセーフティネットだ。エラーが発生した際、どの文字が原因で変換が失敗したのかを特定できる。

1
ON CONVERSION BEGIN;
/ エラーの原因となった文字とソースを特定 /
DCL ERR_CHAR CHAR(1) DEF ONCHAR;
DCL ERR_SOURCE CHAR(256) DEF ONSOURCE;

PUT SKIP LIST(‘データ変換エラー発生’);
PUT SKIP LIST(‘原因文字: ‘ || ERR_CHAR);
PUT SKIP LIST(‘対象文字列: ‘ || ERR_SOURCE);

/ 業務要件に応じて0埋めするなどのリカバリ処理を記述 /
/ 注意: 復帰先の再実行を制御するにはGO TOによる制御が必要な場合が多い /
RESIGNAL; / 呼び出し元へエラーを委譲 /
END;

ここで重要なのは、`ONSOURCE`と`ONCHAR`という組み込み関数(疑似変数)の活用だ。これらを使うことで、ダンプを漁る前に、どのレコードのどの位置が「汚染」されていたのかをログとして残せる。これはマイグレーション時、特に新旧システムのデータ整合性を検証する際、最強の武器となる。

アーキテクトの視点:パックデシマルの符号反転とアベンド解析

移行プロジェクトで頻出するトラブルの一つが、他システム(C言語やCOBOL)から持ち込まれたパックデシマルの「符号ビット」の不一致だ。PL/Iのコンパイラは、`FIXED DEC`の末尾ニブル(4ビット)が正しい符号(x’C’やx’D’)でない場合、情け容赦なく`CONVERSION`条件を発生させる。

もし君がS0C7のダンプを解析しているなら、以下の点を確認してほしい。

1. パックデシマルの正当性: 内部符号が`0x0`〜`0x9`の範囲外(特に負数の時の`0xD`や`0xF`の扱い)で異常を起こしていないか。
2. ポインタを用いた強引なデータ操作: `DCL P PTR;`を用いて対象領域を`BASED`変数にマップしている場合、コンパイラはアライメントチェックをサボることがある。`ALIGNED`と`UNALIGNED`の属性がメモリレイアウトに与える影響を再確認すること。
3. CICS環境におけるエッジケース: CICSオンライン処理でこのエラーが発生した場合、タスクが異常終了し、リソースの同期が取れなくなる恐れがある。`EXEC CICS HANDLE CONDITION`と`ON CONVERSION`が衝突しないよう、ハンドラを局所化することが鉄則だ。

移行の現場へ向けて

JavaやC#へのマイグレーションを行う際、PL/Iのこうした「エラーを発生させてから捕まえる」というスタイルを、例外処理(try-catch)へそのまま翻訳してはいけない。

PL/Iの`ON`ユニットは、コンテキスト(呼び出しスタック)を横断して作用する。この強力だが危険なスコープを、現代的な言語の構造化例外へと紐解くことこそが、真の移行スペシャリストの仕事だ。

最後に一つだけ助言がある。どんなに洗練されたシステムを設計しても、データは必ず裏切る。だが、`ON CONVERSION`を正しく実装したプログラムは、裏切られた瞬間を「エラーログ」という貴重な知見に変えてくれる。

メインフレームの深淵は、こうした地味なエラーハンドリングの蓄積の中にこそ広がっているのだ。

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