【入門編】DB2埋め込みSQLにおけるホスト構造体(HOST STRUCTURE)の利用 – PL/Iの基本構文とデータ制御実践ガイド

こんにちは!メインフレームの世界へようこそ。
JavaやCOBOLの経験がある方なら、新しい言語を学ぶワクワク感と同時に、「なんだこの独特な書き方は……」というレガシー特有の洗礼に、ちょっと戸惑っているかもしれませんね。

大丈夫です、怖くないですよ。一つずつ紐解けば、PL/Iも実はとても合理的で優しい言語なんですから。

今回は、基幹システムの現場で避けて通れない「DB2埋め込みSQLにおけるホスト構造体(HOST STRUCTURE)」について、じっくり解説していきますね。COBOLのグループ項目やJavaのオブジェクトとは一味違う、PL/Iならではの世界を一緒に覗いてみましょう。

—

そもそも「ホスト構造体」ってなに?

JavaやCOBOLでデータベースを操作するとき、こんな風に思ったことはありませんか?
「画面やファイルから読み込んだデータを、そのまま一気にDB2へ登録したい! いちいち変数を一つずつSQLに書くなんて面倒くさい!」って。

COBOLなら `01 CUSTOMER-RECORD.` のようにグループ項目を定義して、`EXEC SQL INSERT INTO CUSTOMER VALUES (:CUSTOMER-RECORD) END-EXEC` なんて書けちゃいますよね。

実は、PL/Iでも全く同じことができるんです。
複数の変数をひとまとめにした「構造体(STRUCTURE)」を定義し、それをDB2のSQL文で一括して参照する――これがホスト構造体です。

—

PL/Iの変数宣言と「予約語がない」という変態的な(褒め言葉です)仕様

ここで、PL/Iのちょっと変わった、というか最初は度肝を抜かれる特徴をお話ししておきます。

JavaやC言語には「予約語(Keyword)」がたくさんあって、`int` や `class` などの単語を変数名に使うことはできませんよね。しかし、PL/Iには原則として予約語というものがありません。

「えっ、じゃあ `IF` とか `READ` って変数名に使えちゃうの?」
その通り使えちゃいます。コンパイラは前後の文脈から「あ、ここは命令だな」「ここは変数名だな」と空気を読んで判断しているんです。

だからこそ、PL/Iのコードを初めて見たとき、変数の宣言方法が独特で少し宇宙語のように感じるかもしれませんが、基本のルールさえ分かれば怖くありません。

—

ホスト構造体定義のルールとコード例

百聞は一見に如かず。実際に、顧客テーブル(`CUSTOMER`)のデータを取得するためのホスト構造体をPL/Iで書いてみましょう。

実務の現場をイメージして、大文字ベース、かつ丁寧なコメント付きでコードを用意しました。

DCL 1 CUST_REC, / レベル1のグループ名(これが構造体の名前になります) /
5 CUST_ID CHAR(5), / 顧客ID(レベル5:実データを持つ項目) /
5 CUST_NAME CHAR(30), / 顧客名 /
5 CUST_BAL DEC FIXED(9,2); / 残高(9桁、小数点以下2桁の10進数) /

/ DB2埋め込みSQLの宣言セクション /
EXEC SQL INCLUDE SQLCA; / DB2通信エリアの取り込み /

/ 実際の処理ロジック /
GET_CUSTOMER_DATA: PROC OPTIONS(MAIN);

/ 顧客IDに特定の値をセット /
CUST_ID = ‘A1234’;

/ ホスト構造体を使って一括でSELECT文を発行する /
EXEC SQL
SELECT CUST_NAME, CUST_BAL
INTO :CUST_REC.CUST_NAME, :CUST_REC.CUST_BAL
FROM CUSTOMER
WHERE CUST_ID = :CUST_REC.CUST_ID;

/ 結果の判定処理(省略) /

END GET_CUSTOMER_DATA;

ここがポイント!データの階層構造

上記のコードを見て、「あれ? `1` とか `5` って何?」って思いませんでしたか?

これがPL/Iの構造体(`STRUCTURE`)の最大の特徴です。COBOLのレベル番号(01, 05など)と非常によく似ていますよね。

  • 一番親となるグループに `1` を振ります。
  • その中にある個別の項目には、大きめの数字(通常は `5` や `10` など)を振って階層を表現します。

これにより、コンパイラは「あ、`CUST_REC` の中に3つのデータがぶら下がっているんだな」と理解し、メモリ上でも連続した領域として綺麗に配置してくれます。

—

コンパイラはどう展開しているの?(裏側の挙動)

私たちプログラマが `INTO :CUST_REC` とスッキリ書いたとき、DB2のプリコンパイラ(DB2のSQL文をPL/Iの原生コードに翻訳する仕組み)やPL/Iコンパイラは、裏側で何をしているのでしょうか?

実は、コンパイラはこれを展開する際、構造体のメンバーをバラして、一つひとつの独立した変数としてDB2へ渡すコードに自動変換しています。

つまり、人間様のコーディングの手間を減らすための「糖衣構文(シンタックスシュガー)」のようなものなんです。
ただし、構造体を使うときは以下の点に注意してください。

1. 修飾が必要な場合がある
同じ名前のメンバーが他の構造体にある場合は、`CUST_REC.CUST_NAME` のようにドット(.)で修飾してあげないと、コンパイラが「どれを指しているのか分からないよ!」と怒ってしまいます(コンパイルエラーになります)。
2. メモリの並び順が命
メインフレームのDB2において、ホスト構造体のメモリレイアウトは非常に厳密です。COBOL同様、パディング(隙間)が生じないようなデータ型の組み合わせにするのが、ベテランアーキテクトのテクニックの見せ所です。

—

まとめ:レガシーの世界も、怖がらずに一歩ずつ

いかがでしたでしょうか?
PL/Iのホスト構造体、そして独自の変数定義のルールについて、少しイメージが湧いてきたのではないでしょうか。

「予約語がない」という自由度の高さや、「1と5の階層数字」といった見た目の古さに最初は面食らうかもしれませんが、根底にある思想は「いかに効率よくデータをコンピュータに処理させるか」という合理的なものです。

JavaやCOBOLで培ったプログラミングの基礎があれば、PL/Iの習得なんてあっという間です。ぜひ自信を持って、日々のバッチ改修やマイグレーション調査に臨んでくださいね。

あなたのメインフレームライフが、実り多いものになるよう応援しています!それではまた。

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