【実務・中級編】プリコンパイル時におけるホスト変数(Host Variables)の宣言規則 – PL/Iの基本構文とデータ制御実践ガイド

PL/IとDB2の蜜月:ホスト変数宣言の「鉄の掟」と実戦的アプローチ

若手エンジニアから、「PL/Iには予約語がないというのに、なぜSQLを叩く時はこんなに窮屈な書き方を強いられるのか?」という愚痴を聞くことがある。確かに、PL/Iの「何でも変数名に使える」という自由さは魅力的だが、DB2という異文化と交わる境界線においては、その自由は時に牙を剥く。

今回は、メインフレームの基幹システムを支えるPL/IとDB2の連携において、避けては通れない「ホスト変数宣言」の深淵に触れていこう。

1. なぜ「EXEC SQL BEGIN DECLARE SECTION」が絶対なのか

PL/Iのコンパイラは非常に寛容だ。極端な話、`IF`や`THEN`さえも変数名として使えてしまう。しかし、DB2のプリコンパイラ(SQLプリプロセッサ)はそうはいかない。

プリコンパイラは、ソースコード全体をスキャンしているわけではない。「この変数はDB2で使うものだ」ということを明示的に教えなければ、SQL文中で参照された変数をただの文字列と見なすか、あるいはエラーとして弾いてしまう。

鉄則: ホスト変数は、必ず `EXEC SQL BEGIN DECLARE SECTION;` と `EXEC SQL END DECLARE SECTION;` の間に閉じ込めること。これは単なる規約ではなく、DB2との通信プロトコルそのものだ。

2. データ型マッピングの「勘所」

PL/Iの型とDB2の型のマッピングで、現場で最もトラブルになりやすいのが「精度の不一致」だ。特に数値型と可変長文字列には細心の注意が必要となる。

| PL/Iの定義例 | DB2のデータ型 | 注意点 |
| :— | :— | :— |
| `FIXED BIN(15)` | `SMALLINT` | 計算用一時変数に多用。桁あふれに注意。 |
| `FIXED BIN(31)` | `INTEGER` | 多くのキー項目で使用。 |
| `CHAR(n)` | `CHAR(n)` | 固定長。空白埋めを忘れると検索漏れの原因に。 |
| `CHAR(n) VAR` | `VARCHAR(n)` | 長さ制御ワード(LL)を持つ。マッピングの主流。 |

特に `CHAR(n) VAR` を使う際は、PL/I内部でその変数に値をセットした後、SQL側で正しい長さが認識されているかを意識してほしい。

3. 実践コード:堅牢なホスト変数宣言とONユニットの活用

現場で即戦力となる記述例を以下に示す。VSAMからDB2へデータを移行するようなバッチ処理を想定し、エラーハンドリング(ONユニット)も含めた構成だ。

/i
/ ———————————————————– /
/ DB2ホスト変数宣言セクション /
/ ———————————————————– /
EXEC SQL BEGIN DECLARE SECTION;
DCL HV_EMP_ID CHAR(6); / 社員番号 /
DCL HV_SALARY FIXED DEC(9,2);/ 給与(DECIMAL推奨) /
DCL HV_IND_SALARY FIXED BIN(15); / NULL判定用インジケータ /
EXEC SQL END DECLARE SECTION;

/ ———————————————————– /
/ メイン処理の一部 /
/ ———————————————————– /
/ ONユニットによる入出力エラーの捕捉 /
ON ENDFILE(VSAM_FILE) BEGIN;
PUT SKIP LIST(‘入力ファイル終了’);
END;

/ データ取得処理 /
EXEC SQL
SELECT SALARY INTO :HV_SALARY :HV_IND_SALARY
FROM EMP_TABLE
WHERE EMP_ID = :HV_EMP_ID;

/ SQLCODEの確認は必須(0以外はエラーとみなすのが現場の定石) /
IF SQLCODE ^= 0 THEN DO;
PUT SKIP LIST(‘DB2エラー発生: ‘ || TRIM(CHAR(SQLCODE)));
SIGNAL FINISH;
END;

4. 現場のシニアからのアドバイス:BUILTIN関数を使いこなせ

PL/Iの強みは、標準で提供されている `BUILTIN` 関数の豊富さにある。ホスト変数をDB2に渡す前、あるいはDB2から受け取った後にデータを加工する際、これらを適切に使うことでコードの可読性が格段に上がる。

  • `TRIM` 関数: 可変長文字列の空白を除去する。`WHERE` 句での検索条件作成時、無駄な空白が入るとインデックスが効かないことがある。必ず `TRIM` で正規化してから渡す癖をつけよう。
  • `SUBSTR` 関数: 複雑なキー体系を扱う際、特定の桁だけを切り出すには必須だ。

最後に

ホスト変数の宣言規則は、一見すると堅苦しい「お作法」に見えるかもしれない。しかし、このルールを厳格に守ることこそが、深夜のトラブルシューティングを回避し、何十年先も動く堅牢なシステムを維持する唯一の道だ。

PL/Iという古くからの相棒と、DB2という強力なエンジン。この二つの特性を理解し、コードに魂を込めること。それが、真のシステムアーキテクトへの第一歩だ。次回の改修でも、この基本を忘れないでいてほしい。

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