【入門編】ENVIRONMENT属性のKEYED/SEQUENTIAL/DIRECT指定によるアクセスパスの決定 – PL/Iの基本構文とデータ制御実践ガイド

こんにちは!IBMメインフレームの世界へようこそ。
JavaやCOBOLといったモダン、あるいは王道なビジネス言語をご経験の方にとって、PL/I(ピーエルアイ)という名前を聞くだけで「なんだか難解そう」「歴史のありすぎる黑魔術みたい……」と、身構えてしまうかもしれませんよね。

でも、安心してください。怖がる必要はまったくありません!
今回は、PL/Iのデータ制御において最も重要であり、かつ初心者が最初に「おっ?」と躓きやすい「VSAMデータセットへのアクセスパス(ENVIRONMENT属性の指定)」について、じっくりと紐解いていきたいと思います。

Javaのコレクション操作や、COBOLの`ORGANIZATION IS INDEXED`といった概念を知っている方なら、実は「なるほど、そういうことね!」とスッと腑に落ちるはずです。さあ、コーヒー片手にリラックスして進めていきましょう。

—

そもそもPL/Iの「データアクセス」ってどうなっているの?

Javaでデータベースやファイルを扱うときは、JDBCを使ったり、`BufferedReader`を開いたりしますよね。COBOLなら、`SELECT`文でファイル名と物理ファイルを結びつけ、`READ`や`WRITE`を叩きます。

PL/Iでも基本の考え方は同じなのですが、「コンパイラが私たちの意図をどうくみ取るか」が非常にユニークなんです。
PL/Iには、COBOLのような「厳格な予約語のしばり」が驚くほど少ないという特徴があります(この話はまた別の機会にじっくり!)。そのため、私たちが「このファイルをどう扱いたいのか」を属性(Attribute)という形でファイル変数に優しく、しかし明確に教えてあげる必要があります。

その主役が、今回焦点を当てる `ENVIRONMENT`属性 です。

—

VSAMのアクセスパスを決める3つのキーワード

メインフレームの代表的なデータ管理システムであるVSAM(KSDS:主記憶順データセットなど)をPL/Iから読み書きする場合、ファイルを定義する `DECLARE`(DCL)文の中で、主に次の3つのキーワードを使い分けます。

1. `SEQUENTIAL`:順番に(上から下へ)コツコツ読む・書く
2. `DIRECT`:「このキーのデータをちょうだい!」とピンポイントで狙い撃つ
3. `KEYED`:キー(鍵)を使ってデータを特定できるようにする宣言

これらを`ENVIRONMENT`(環境)というカッコの中に詰め込んでコンパイラに伝えると、コンパイラは「なるほど、このプログラムはこういう動きをするんだな。じゃあ、それに合わせた最適なアクセスルーチン(機械語の裏方さん)を組み立てておこう」と、裏でこっそり準備をしてくれるのです。

それぞれの挙動について、もう少し具体的に見ていきましょう。

—

パターン1:SEQUENTIAL(順次アクセス)

「本のページを1ページずつめくる」ような読み方

もしあなたが、全件ファイルを頭から尻尾まで舐めるように処理するバッチプログラム(例えば、全顧客の月次集計など)を書くなら、SEQUENTIALの出番です。

  • 使う命令: `GET DATA` や `READ`(順次用)
  • コンパイラの生成するコード: 次のレコードへのポインタをスルスルと進める、効率的なストリーミング型のルーチンを作ります。

1
/ 順次アクセス(SEQUENTIAL)によるVSAMファイルの読み込み例 /
DCL CUST_FILE FILE RECORD
ENV(VSAM
SEQUENTIAL); / 順番に読み込むことをコンパイラにお知らせ /

DCL 1 CUST_REC,
5 CUST_ID CHAR(5),
5 CUST_NAME CHAR(30);

/ ファイルを開いて上から順に読み込むループ /
OPEN FILE(CUST_FILE) INPUT;

DO WHILE(NOT_EOF);
READ FILE(CUST_FILE) INTO(CUST_REC);
/ ここでゴニョゴニョとデータを処理する /
END;

CLOSE FILE(CUST_FILE);

まるで文庫本を1ページ目から順に読んでいくような感覚ですね。迷いがなくてとてもシンプルです。

—

パターン2:DIRECT(直接アクセス)

「電話帳から特定の人のページをパッと開く」ような読み方

次に、画面からのオンラインリクエストや、リアルタイムで特定のマスターデータを引き当てたいバッチ(例:「社員番号 ‘12345’ の人だけピンポイントで更新したい!」)の場合です。ここで登場するのが `DIRECT` です。

  • 使う命令: `READ KEY` や `REWRITE`
  • コンパイラの生成するコード: VSAMの索引(インデックス)を辿って、一発で該当レコードの場所(RBAなど)を特定する、ちょっと高度なダイレクト・アクセス用のルーチンを組み立てます。

1
/ 直接アクセス(DIRECT)によるVSAMファイルの読み書き例 /
DCL MSTR_FILE FILE RECORD
ENV(VSAM
DIRECT / ピンポイントでアクセスする指定 /
KEYED); / キーを使用する宣言がセットで必須! /

DCL 1 MSTR_REC,
5 EMP_ID CHAR(4), / これが検索キーになる /
5 EMP_DATA CHAR(50);

OPEN FILE(MSTR_FILE) UPDATE; / 更新モードでオープン /

/ 探したい社員番号をセットして一発読み込み! /
EMP_ID = ‘A108’;
READ FILE(MSTR_FILE) INTO(MSTR_REC) KEY(EMP_ID);

/ データを書き換えて反映 /
EMP_DATA = ‘山田 太郎 (更新済み)’;
REWRITE FILE(MSTR_FILE) FROM(MSTR_REC);

CLOSE FILE(MSTR_FILE);

ここで「あれ?」と気づいた鋭い読者の方、素晴らしいです。`DIRECT`を指定するとき、ほとんどの場合で `KEYED` というキーワードがセットで必要になります。「キー(鍵)を使って直接扉を開けに行くんだよ」という意思表示ですね。

—

パターン3:DYNAMIC(両刀使い)

「順番にも読むし、途中でピンポイントも引く」欲張りさん

実は、もう一つ重要なモードがあります。それが `DYNAMIC` です。
これは、「基本は順番に舐めていくけれど、途中で『おっ、このキーのデータもちょっと確認したいな』と思ったら、その場でキー指定の直接アクセスに切り替えたい!」という、なんとも欲張りで便利なモードです。

  • 指定方法: `ENV(VSAM DYNAMIC KEYED)`
  • コンパイラへの影響: 順次読み込みと直接アクセスの「いいとこ取り」ができるルーチンを生成するため、コンパイラは少しだけ複雑な舵取りをしてくれます。実務のマイグレーション現場でも非常によく使われるパターンです。

—

コンパイラが裏で行っていること:アクセスルーチンの裏側

JavaやCOBOLのフレームワークを使っていると、ファイルアクセスの裏側(OSのBSAMやVSAMマクロ、ACB/RPLといった制御ブロックのやり取り)は完全に隠蔽されていますよね。

しかし、PLIコンパイラは、私たちが書いた `ENV(VSAM DIRECT KEYED)` などの属性を読み解き、「このプログラムはOSに対してどんなマクロ(PL/Iランタイムライブラリを介して)を発行すべきか」を機械語レベルで完全に切り替えています。

  • `SEQUENTIAL` ならば、OS側の順次バッファリングを最大限に活かすコードに。
  • `DIRECT` ならば、ランダムアクセス用のレコード管理ルーチンに。

もし、プログラムの中身は `READ … KEY(…)` と書いてあるのに、ファイルの宣言側で `ENV(SEQUENTIAL)` と書き間違えてしまったらどうなるでしょう……?
そう、コンパイルエラーになるか、あるいは実行時に「そんなアクセス方法、聞いてないよ!」という恐ろしいシステム異常(abend:異常終了)を引き起こしてしまいます。

だからこそ、「自分がこのファイルをどう扱いたいか」を正しくPL/Iの宣言部に翻訳してあげることが、バグのない堅牢なメインフレームシステムを作る最大の秘訣なのです。

—

まとめ

いかがでしたでしょうか? レガシーなPL/Iの世界も、一つひとつのキーワードが持つ意味(なぜこの指定が必要なのか)を紐解いていくと、意外とロジカルで優しい言語であることが伝わったのではないでしょうか。

  • 順番に読むなら `SEQUENTIAL`
  • ピンポイントで狙うなら `DIRECT`(そしてお供に `KEYED`)
  • どっちもやりたい欲張りさんは `DYNAMIC`

この基本 さえ押さえておけば、VSAMデータセットを相手にするバッチプログラムの改修や移行調査で戸惑うことはもうありません。

「レガシーシステムなんて怖くない!」
ぜひ、自信を持って日々の開発やマイグレーションに臨んでくださいね。次回の解説もお楽しみに!

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