【実務・中級編】DB2埋め込みSQLにおけるホスト変数とPL/Iデータ型のマッピング – PL/Iの基本構文とデータ制御実践ガイド

現場の知恵:PL/IとDB2の「絶妙な距離感」を極める――ホスト変数マッピングの落とし穴

メインフレームの現場で長く戦っていると、最新の分散系から来たエンジニアがPL/Iのデータ定義を見て「なぜこんなに冗長なのか?」と首を傾げる光景によく出会う。だが、我々が守り続けてきたこの「型」への執着こそが、24時間365日止まらない基幹システムの安定性を支えているんだ。

今日は、DB2埋め込みSQLにおけるホスト変数のマッピング、特に`VARCHAR`と`CHARACTER VARYING`の微妙な距離感について、現場の教訓を交えて解説しよう。

1. そもそも、なぜホスト変数の「型」が重要なのか

DB2のSQL文の中で、PL/Iの変数をホスト変数として使うとき、DB2とPL/Iの間では「暗黙の型変換」が行われる。ここで、サイズや型の定義が微妙にズレていると何が起きるか?

最も多いのが、「インデックスが効かなくなる(性能劣化)」「予期せぬ切捨て(データ欠損)」だ。特にバッチ処理の改修で、既存の定義を安易に書き換えると、実行計画が激変して夜間バッチがパンクする。この「沈黙の性能劣化」は、メインフレームエンジニアにとって最大の悪夢だ。

2. VARCHAR vs CHARACTER VARYING:正しいマッピングの作法

まずは、基本の対応表を頭に叩き込んでおこう。

| DB2の型 | PL/Iの推奨型 | 注意点 |
| :— | :— | :— |
| CHAR(n) | CHAR(n) | 固定長。空白詰めが基本。 |
| VARCHAR(n) | CHAR(n) VARYING | 先頭2バイトに長さが入る構造体として扱われる。 |

ここで重要なのは、PL/Iの`VARYING`属性を使うと、コンパイラが自動的に「長さフィールド(2バイト)」+「データ本体」の構造を生成してくれる点だ。DB2はSQLDA(SQL記述域)を通じて、このPL/Iの構造を正しく解釈する。

もし、ここを`CHAR(n)`(固定長)で宣言して、DB2の`VARCHAR`列に突っ込んだり、逆に受け取ったりするとどうなるか? 致命的なメモリ破壊には至らないが、DB2側で「固定長文字列」として解釈され、末尾の不要な空白が値の一部とみなされるといった不整合が頻発する。

3. 実践コード:保守現場の定石

以下のコード例を見てほしい。これが、我々が現場で「安全」と判断するホスト変数の定義テンプレートだ。

1
//
/ プログラム名: DB2_ACCESS_SAMPLE /
/ 概要: ホスト変数定義とSQL埋め込みの標準的アプローチ /
//
DB2_ACCESS: PROCEDURE OPTIONS(MAIN);

/ 構造体でホスト変数をグループ化するのが鉄則 /
DCL 1 H_RECORD,
3 H_CUST_ID CHAR(8), / 固定長キー /
3 H_CUST_NAME CHAR(40) VARYING, / 可変長:これがVARCHAR用 /
3 H_IND_NULL FIXED BIN(15); / インジケータ変数 /

/ VSAMアクセス等の他処理と混在する場合はONユニットで制御 /
ON ERROR BEGIN;
PUT SKIP LIST(‘予期せぬエラー発生。ダンプを取得して解析せよ。’);
SIGNAL CONDITION(DB2_ABEND);
END;

/ データベースへのアクセス処理 /
EXEC SQL
SELECT CUST_NAME
INTO :H_CUST_NAME:H_IND_NULL
FROM CUST_TABLE
WHERE CUST_ID = :H_CUST_ID;

/ 取得結果の検証:LENGTH組み込み関数で長さを確認 /
IF LENGTH(H_CUST_NAME) > 0 THEN DO;
/ VARYING変数はLENGTH関数で有効長を取得できるのが強み /
PUT SKIP EDIT(‘取得した顧客名:’, H_CUST_NAME) (A, A);
END;

END DB2_ACCESS;

このコードのポイント

1. インジケータ変数の活用: `NULL`許容カラムに対しては、必ず`FIXED BIN(15)`のインジケータを用意すること。これを怠ると、`NULL`取得時に「-305」エラーでプログラムが落ちる。
2. VARYINGの利便性: `CHAR(40) VARYING`を使うことで、`LENGTH`組み込み関数がそのまま使え、バッチ処理での文字列操作が格段に楽になる。
3. 構造体定義: `DCL 1`のグループ化は、DB2のホスト変数だけでなく、VSAMのレコードレイアウトとの整合性を取るためにも必須の作法だ。

4. ベテランからのアドバイス

「とりあえず動くから」と、`CHAR(n)`でVARCHAR列を受けていないだろうか?

もしマイグレーションや大規模改修の機会があるなら、一度ソース内のデータ宣言を総点検してほしい。DB2のカタログ情報とPL/Iの宣言が1対1で整合しているかを確認するだけで、バッチの実行速度や安定性は劇的に改善する。

PL/Iは古い言語と言われるが、その厳格な型定義は、大規模システムにおいて「データが壊れる隙を与えない」という強力な防御壁になっているんだ。この特性を理解し、使いこなせれば、君はもう一段上のアーキテクトになれるはずだ。

次は、ONユニットを使ったより複雑なエラーリカバリについて話すとしよう。現場でのトラブルは、常に「想定外」の場所からやってくるものだからな。

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