鉄壁のデータ整合性を求めて:PL/I `ON CONVERSION` による例外処理の深淵
メインフレームの現場で何十年と生き抜いてきたシステムなら、一度は目にするであろう光景があります。深夜バッチの真っ只中、突如として吐き出されるシステム・アベンド(S0C7)。「データ例外(Data Exception)」の四文字に、背筋が凍る思いをした経験はないでしょうか。
特に外部システムから受け取るフラットファイルや、古いCOBOL資産から引き継いだ汚染データが混入した際、PL/Iの数値変換は極めてシビアに反応します。今回は、システムアーキテクトとして、この「CONVERSION条件」をいかに飼い慣らし、アベンドを回避してプログラムの堅牢性を担保するか、その実装哲学を紐解いていきましょう。
—
1. なぜ、標準的なIF判定だけでは不十分なのか
多くのジュニア・エンジニアは、`NUMERIC`関数でチェックすれば万全だと考えがちです。しかし、基幹システムの現場は甘くない。パックデシマル(COMP-3)の内部符号が壊れている場合、あるいは特定の文字コード変換ミスで制御文字が混入した場合、標準的な論理チェックをすり抜けるケースは枚挙にいとまがありません。
特にマイグレーション(Java/C#等への移行)を控えたシステムにおいて、こうした「PL/I特有の寛容さ(あるいは厳格さ)」を理解せずにロジックを書き換えると、ターゲット環境で不可解な数値エラーが多発することになります。
2. ON CONVERSIONによる防御的プログラミング
PL/Iの真骨頂は、ハードウェアレベルの例外を言語仕様としてキャッチできる点にあります。以下に、不正なデータを「0」としてリカバリし、エラーログを出力して処理を継続する実践的なサンプルを示します。
1
/ プログラムのメイン構造 /
RECOVERY_PROC: PROCEDURE OPTIONS(MAIN);
DCL INPUT_CHAR CHAR(10) INIT(‘123A5’); / 不正データが含まれるケース /
DCL WORK_NUM FIXED DEC(7,0);
/ CONVERSION条件のトラップ設定 /
ON CONVERSION BEGIN;
/ 不正データ検知時のリカバリ処理 /
PUT SKIP LIST(‘警告: 数値変換エラーを検知 – 不正な値を0として処理します’);
WORK_NUM = 0;
/ GOTOを用いたリカバリ後の復帰 /
GOTO CONTINUE_PROCESS;
END;
/ 数値変換の試行 /
WORK_NUM = INPUT_CHAR;
CONTINUE_PROCESS:
PUT SKIP LIST(‘結果値: ‘ || WORK_NUM);
END RECOVERY_PROC;
ポイント:なぜGOTOを使うのか?
`ON`ユニット内で`GOTO`を使うのは、現代的なプログラミング規約では敬遠されがちです。しかし、PL/Iの例外処理において、発生したその瞬間の文脈を捨てて正常系フローへ強制的に復帰させるには、この手法が最も副作用が少なく、コンパイラにとっても最適化の妨げになりにくいのです。
3. マイグレーションを見据えたアーキテクチャ設計
もし貴方がJavaやC#への移行を検討しているなら、この`ON CONVERSION`の挙動こそが「最大の壁」になります。
- パックデシマルの符号反転: 汎用機では `0C`(正)が `0F`(正)と混在しても許容されるケースがありますが、オープン系の厳格な型判定では即座に例外になります。PL/I側で`ON CONVERSION`を使って正規化しておくことは、移行後のデータ品質を保証する「先行投資」です。
- DB2への埋め込みSQL: SQLCODEが返る前の「変換フェーズ」でアベンドが発生すると、ダンプ解析は極めて困難になります。DB操作前には必ず正規化のレイヤーを挟むのが、枯れたアーキテクトの矜持です。
- 最適化オプション(OPTIMIZE(2|3)): コンパイラ最適化をかけると、例外発生箇所のレジスタ状態がソースコードの行番号と完全に一致しなくなることがあります。信頼性を極めるなら、変換処理の前後には `UNALIGNED` な構造体へのコピーを行い、境界条件を明示的に制御してください。
4. ダンプ解析の現場から:アベンドを恐れるな
`ON CONVERSION`を適切に実装していても、なお防げない事態はあります。その際、ダンプリスト上の「プログラムのどこで、どの変数が壊れたのか」を特定するには、`DCL`定義における`ALIGNED`属性の指定や、`STORAGE`クラスの配置を意識する必要があります。
万が一、アベンドした場合は、必ず`SYSUDUMP`または`SYSABEND`を採取してください。PL/Iの実行時サブルーチン(PL/I Library)が、どのオフセットで`CONVERSION`例外をスローしたかを確認すれば、データ側の問題なのか、メモリ破壊(ポインタの不正操作など)によるものなのか、瞬時に見極めることができます。
—
結びに代えて
PL/Iは単なる「古い言語」ではありません。ハードウェアの特性を、人間の論理と直結させるための極めて精密なインターフェースです。
システム移行を成功させる鍵は、新言語の機能を探すことよりも、PL/Iがこの数十年、どのような例外処理によって「止まらないシステム」を実現していたかを紐解くことにあります。`ON CONVERSION`の実装は、その第一歩に過ぎません。
基幹システムの信頼性を次世代へ繋ぐために。貴方のコードが、次の30年を支える強固な防壁となることを願っています。
