こんにちは。IBMメインフレームの世界へようこそ。
Javaの綺麗なオブジェクト指向や、COBOLの堅実なデータ処理に慣れ親しんできた方にとって、PL/Iは少し「独特なクセ」を持つ老練な職人のような言語に見えるかもしれません。
しかし、ご安心ください。PL/Iは「科学技術計算」と「事務処理」の両方をこなせるよう設計された、非常に懐の深い言語です。今日は、メインフレームの現場で遭遇する「厄介なアイツ」、データ型不一致(CONVERSION)を華麗にさばく方法についてお話しします。
—
なぜ、数値項目に「ゴミ」が混ざるのか?
Javaであれば `Integer.parseInt()` で例外がスローされるところですが、メインフレームのバッチ処理では、数百名、数千名の顧客データが流れる中で、突然「数字が入るはずの場所に、誰かが誤ってスペースや記号を紛れ込ませた」という事態が起こります。
PL/Iの数値型(`FIXED BINARY` や `FIXED DECIMAL`)は、メモリ上で非常に厳密に管理されています。ここに数字以外の「ゴミ」が流れ込むと、コンパイラは即座に「CONVERSION条件」という非常事態を宣言します。
ONユニットという「転ばぬ先の杖」
PL/Iには、こうしたエラーをプログラム終了させずに、裏側でこっそり処理する「ONユニット」という魔法のような仕組みがあります。
/i
/ プログラムのメインブロック /
MAIN_PROC: PROCEDURE OPTIONS(MAIN);
/ 予期せぬデータ混入をキャッチするONユニットを定義 /
ON CONVERSION BEGIN;
/ ここで何が起きたかログを吐いて、処理を継続させる /
PUT SKIP LIST(‘警告: 数値変換エラーが発生しました。不正データを検知!’);
/ 0に置き換えて処理を続行させる(魔術的な手法) /
/ CONVERSION条件では、代入操作で値を修正してリトライさせることが可能 /
SUBSTR(ONSOURCE, ONCHARINDEX, 1) = ‘0’;
RETRY;
END;
DCL WS_AMOUNT FIXED DECIMAL(5, 0);
DCL INPUT_DATA CHAR(5) INIT(’12A45′); / ここに’A’という不正文字がある /
/ 変換処理を実行 /
WS_AMOUNT = INPUT_DATA;
PUT SKIP LIST(‘処理結果: ‘, WS_AMOUNT);
END MAIN_PROC;
このコードの「ここが面白い!」ポイント
1. ON CONVERSION: このブロックを書くだけで、プログラム中のどこで数値変換エラーが起きても、すべてここで一括捕獲できます。Javaの `try-catch` をプログラムの全域に貼り付けるような強力なガードです。
2. ONSOURCE / ONCHARINDEX: PL/Iは優秀です。エラーが起きた瞬間に「どの変数で起きたか(ONSOURCE)」と「何文字目がダメだったか(ONCHARINDEX)」を自動的に保持してくれます。
3. RETRY: これが肝です。エラー箇所を0で埋め直した後、もう一度変換をやり直す(リトライ)ことで、バッチを止めることなく処理を完走させることができます。
—
初学者が気をつけるべき「暗黙の変換」
PL/Iが「怖い」と感じる理由の多くは、この「暗黙の変換」にあります。
例えば、`FIXED DECIMAL`(事務計算用)と `FIXED BINARY`(高速計算用)を混ぜて計算すると、PL/Iは親切心から裏側で型変換を行います。これがデータ桁落ちや、予期せぬCONVERSION条件を引き起こす原因になるのです。
- アドバイス: 「なんとなく」で型を混ぜないこと。データ宣言(`DCL`文)で属性をしっかり指定し、計算のたびにキャストを意識するだけで、バグの9割は防げます。
最後に:メインフレームは怖くない
「PL/Iは古い」と言われることもありますが、数十年前から今日まで、金融や公共の基幹システムで一度も止まることなく動き続けていること自体が、この言語の堅牢さを証明しています。
今回紹介した `ON` ユニットは、まさに「止まらないシステム」を作るための先人の知恵です。エラーをただの失敗と捉えるのではなく、「どうやってリカバリして業務を完遂させるか」を考える。このエンジニアリングの姿勢こそが、メインフレームの世界で最も重宝されるスキルです。
皆さんの現場でも、ぜひこの「転ばぬ先の杖」を活用して、安定したバッチ運用を目指してくださいね。また何か躓いたときは、いつでも聞きに来てください。一緒に紐解いていきましょう!
