こんにちは!メインフレームの世界へようこそ。
JavaやCOBOLといった他のプログラミング言語の経験がおありなら、PL/I(ピーエルアイ)という名前を聞いて「なんだか古臭くて難しそうだな…」と身構えてしまっているかもしれませんね。でも、大丈夫ですよ。一つずつ紐解いていけば、決して怖くありません。
今回は、基幹システムのバッチ処理などで誰もが一度は頭を抱える「データ変換エラー(CONVERSION条件)」と、そのスマートな手当て方法について、現場のノウハウを交えながら優しく解説していきますね。
—
そもそも、PL/Iの変数ってちょっと変わっている?
JavaやCOBOLから来た人が最初につまづくのが、PL/Iの独特なデータ宣言です。
例えば、COBOLなら `PIC X(10)` とか `PIC 9(5) COMP` のように書くところを、PL/Iでは以下のように書きます。
1
DCL WK_INPUT_STR CHAR(10); / 10バイトの文字型変数 /
DCL WK_AMOUNT FIXED DEC(5); / 5桁の数値型変数 /
ここで「あれ?」っと気づいた方、鋭いですね。
PL/Iには、他の言語でよくあるような「厳密な予約語(Keywords)」の縛りがほとんどないという、非常にユニークな特徴があります。どういうことかと言うと、`IF` や `DO` といった制御構文の名前を除けば、多くの単語をプログラマが自由に変数の名前(識別子)として使えてしまうのです。
そのため、最初のうちは「どこまでが命令で、どこからが変数名なの!?」と混乱しがちですが、コンパイラは前後の文脈をちゃんと読んで解釈してくれますので、安心してリラックスしていきましょう。
—
「あれっ、数値が入らない!?」CONVERSION条件の恐怖
さて、本題に入りましょう。
画面や外部ファイルから受け取った「文字データ」を、計算用の「数値データ」に代入して計算させようとした時、こんな悲劇が起きることがあります。
1
/ 文字列の中に、うっかりスペースや漢字、英字が混ざっていた! /
WK_INPUT_STR = ‘ 123A ‘;
WK_AMOUNT = WK_INPUT_STR; / ここでガチャン!とシステムが止まる /
Javaの `NumberFormatException` や、COBOLのデータ転記エラー(数字以外の文字が入っていてアボート)を想像してください。まさにあれです。
PL/Iでは、文字型から数値型へデータを変換する際、その中身が数字としてふさわしくない場合、「CONVERSION(コンバージョン)条件」という例外(シグナル)が発生します。
これをそのまま放置すると、容赦なくバッチジョブが異常終了(ABEND)し、夜中に運用担当者から悲鳴のような電話がかかってくることになります。
—
`ON CONVERSION` でエラーを優しく捕まえよう
そこで登場するのが、今回の主役である `ON CONVERSION` 構文です。
Javaの `try-catch` ブロックをイメージしてもらうと分かりやすいかもしれません。「もし変換エラーが起きたら、プログラムを落とす代わりに、こうして処理してね」とあらかじめコンパイラにお願いしておく仕組みです。
実際のコードを見てみましょう。
1
/================================================================/
/ CONVERSIONエラーのトラップと不正データ救済のサンプル /
/================================================================/
TEST_CONV: PROC OPTIONS(MAIN);
DCL WK_INPUT_STR CHAR(6) INIT(‘1234 A’); / 末尾にスペースと文字混じり /
DCL WK_AMOUNT FIXED DEC(5,0); / 5桁の数値項目 /
DCL ERROR_FLAG CHAR(1) INIT(‘0’); / エラー検知フラグ /
/ — ここがポイント!CONVERSION条件の監視をスタート — /
ON CONVERSION
BEGIN;
/ エラー発生時にここに飛び込んできます /
ERROR_FLAG = ‘1’;
/ ログなどに不正なデータを残すための親切設計 /
PUT SKIP LIST(‘【警告】数値変換エラーを検知しました。対象データ:’, WK_INPUT_STR);
/ 万が一の無限ループを防ぐため、安全なデフォルト値を強制代入して続行 /
WK_AMOUNT = 0;
END;
/ — 実際に変換を試みる処理 — /
PUT SKIP LIST(‘変換前の文字列:’, WK_INPUT_STR);
/ この代入の瞬間にエラーが起きれば、上のONブロックへジャンプします /
WK_AMOUNT = WK_INPUT_STR;
/ — 結果の判定 — /
IF ERROR_FLAG = ‘1’ THEN
PUT SKIP LIST(‘処理は継続しましたが、データ不正のため要確認です。’);
ELSE
PUT SKIP LIST(‘変換成功! 数値:’, WK_AMOUNT);
END;
END TEST_CONV;
このコードの優しいポイント
1. バッチを止めずに生き延びる
`ON CONVERSION` の中でエラーフラグを立て、安全な値(この例では `0`)を代入してあげることで、ジョブがいきなり異常終了するのを防げます。「一部のデータがおかしいせいで、数百万件の処理全体が止まってしまった…」という最悪の事態を回避できるわけです。
2. 不正データの特定が簡単
`PUT SKIP LIST` などを使って、どのデータが原因でエラーになったのかをシームレスに出力させることができます。レガシー移行の現場では、この「原因データの特定」が何よりも重要になります。
—
まとめ:レガシーの世界も、怖がる必要はありません
いかがでしたでしょうか?
PL/Iの `ON CONVERSION` は、一見するとレガシー特有の呪文のように見えるかもしれませんが、やっていることは現代のプログラミング言語における例外処理(Exception Handling)と本質的には同じです。
「文字を数値に変えるときに変なデータが来たらどうしよう?」という不安に対して、「こうやってあらかじめ網(トラップ)を張っておけば大丈夫だよ」とPL/Iは優しくサポートしてくれます。
基幹システムのマイグレーションや保守でPL/Iコードに出会っても、どうか深呼吸して、一つずつ紐解いていってくださいね。あなたのシステム開発ライフが、少しでも快適なものになりますように!
