1. 導入:なぜ「SEARCH ALL文」が重要なのか
COBOL開発の現場では、メモリ上に展開したテーブル(配列)から特定のデータを探す処理が頻繁に行われます。単純なループ処理(PERFORM)で頭から順に調べる「逐次検索」は、データ量が少ないうちは良いのですが、数万件以上の大規模なマスタとなると非常に時間がかかってしまいます。ここで登場するのが「SEARCH ALL文」です。これは「二分探索(バイナリサーチ)」というアルゴリズムを自動で行う命令で、処理速度を劇的に向上させ、プログラムのパフォーマンス問題を解決するために不可欠な技術です。
2. 基礎知識:二分探索の仕組み
通常、テーブル検索といえば「先頭から順番に確認する」方法が一般的ですが、二分探索は異なります。テーブルがあらかじめ「昇順(ASCENDING)」または「降順(DESCENDING)」に並んでいることを前提に、真ん中の値をまず調べます。探している値がそれより大きければ後半を、小さければ前半を対象にする……という手順を繰り返すことで、検索範囲を半分ずつ絞り込んでいく手法です。この仕組みにより、計算量は飛躍的に少なくなります。
3. 実装と解決策
SEARCH ALL文を使用するには、データ定義(WORKING-STORAGE SECTION)で以下の2つの条件を満たす必要があります。
1. OCCURS句に「INDEXED BY」を指定して、指標(インデックス)を用意する。
2. テーブルの定義に「ASCENDING KEY」または「DESCENDING KEY」を指定し、ソート済みであることをコンパイラに伝える。
この準備さえできていれば、SEARCH ALL文を書くだけで、複雑なループ制御やインデックスの初期化を自動的にコンパイラが処理してくれます。
4. サンプルプログラム
以下のコードは、社員番号をキーにしてマスタ情報を検索する例です。そのままコピーして、学習用としてお使いください。
IDENTIFICATION DIVISION.
PROGRAM-ID. SEARCH-SAMPLE.
DATA DIVISION.
WORKING-STORAGE SECTION.
- テーブル定義:社員番号で昇順ソートされている前提
01 WS-EMP-TABLE.
05 WS-EMP-ITEM OCCURS 100 TIMES
ASCENDING KEY IS WS-EMP-ID
INDEXED BY WS-IDX.
10 WS-EMP-ID PIC X(05).
10 WS-EMP-NAME PIC X(20).
01 WS-SEARCH-KEY PIC X(05) VALUE ‘A0002’.
01 WS-FOUND-FLAG PIC X(01) VALUE ‘N’.
PROCEDURE DIVISION.
- 検索実行
- SEARCH ALLは対象テーブルを二分探索する
SEARCH ALL WS-EMP-ITEM
- 見つかった時の条件
WHEN WS-EMP-ID(WS-IDX) = WS-SEARCH-KEY
DISPLAY ‘発見しました: ‘ WS-EMP-NAME(WS-IDX)
MOVE ‘Y’ TO WS-FOUND-FLAG
- 見つからなかった時の処理
WHEN AT END
DISPLAY ‘対象データは見つかりませんでした’
END-SEARCH.
STOP RUN.
5. 応用・注意点:現場で陥りやすい罠
現場で最も多いミスは、「ソートされていないデータに対してSEARCH ALL文を使ってしまうこと」です。二分探索は「データが正しく整列されている」という前提があって初めて成立します。もしデータがバラバラの状態でSEARCH ALLを実行すると、誤った結果を返したり、データが見つからないという現象が発生します。
また、条件式(WHEN)には「=」以外の演算子(> や <)は指定できません。複雑な条件で検索したい場合は、まずはSEARCH ALLでキーを特定し、その後に詳細なチェックを行うといった工夫をしてください。この基本を押さえるだけで、あなたの書くプログラムは驚くほど高速で安定したものになりますよ。

コメント