【COBOL 読み3-10-9】SEARCH ALLで事故りはともだちを回避

🧩今日の学び
SEARCH ALLは二分探索であり、並び順とINDEXが崩れると正しいデータでも見つからない
・速さを選ぶ命令ほど、使う側に「保証責任」が発生するというCOBOL思想を理解する
・「速い=正しい」ではなく、「準備が正しければ速い」という視点が重要

係長)よし、次だ。

勘違いされやすくて、よく事故るやつSEARCH ALLだ。

なるお)なんで、そんなのばっかなんすか…。

係長が引き寄せるんじゃないすか。類は友を呼ぶって言うじゃないすか。

係)お前は事故りとともだちだろ。

な)キャプテン翼っぽいってことっすね!足長いっすもんね!

係)あーそうだな。

な)もうちょっと付き合ってくれるもんじゃないです?

目次

SEARCH ALLは上級者専用コマンド

係)SEARCH ALLはな「条件を守れた者だけが使える命令」だ。

まず、SEARCHとの違いだが、

SEARCH

  • いわゆるしらみつぶし
  • 上から順番に見る
  • 1件ずつ確認

こういう形だ。

SEARCH ITEM-REC
    WHEN ITEM-ID(IDX) = TARGET-ID
        ...
END-SEARCH

な)ふんふん。

SEARCH ALL

係)SEARCH ALL

  • いわゆる二分探索
  • 真ん中から見る
  • 半分、半分と範囲を潰す

こういう形だ。

SEARCH ALL ITEM-REC
    WHEN ITEM-ID(IDX) = TARGET-ID
        ...
END-SEARCH

な)ふむふむ、なんか構造っぽいのはかわんないすね。

最大の地雷:並び順とINDEXという絶対条件

係)ま、ここまではいいんだが、条件がある

条件①:並んでいなきゃダメ

係)ここが最大の地雷だ。

  • テーブルはキー順にソート済み
  • 昇順か降順かも決まっている
  • 途中で順番が崩れてたら「あるのに見つからない」

お前が一番やりがちなやつだな。

な)そんな新卒ムーブはかまさないですって!天性のコボラーと呼ばれて久しいんですからね!

係)どこに久しい要素があるんだよ…

条件②:INDEXED BYが必須

係)SEARCHSEARCH ALLSUBSCRIPTじゃダメだ。インデックスでしか動かないぞ。

「番号で回す」発想は通用しないからな。

な)なんかそこが分かりづらくしてるんじゃないすかね⋯

係)インデックスを使うんだから、先にインデックス処理すると覚えておけばいいだろ。

条件③:比較条件は単純

ただし、

  • 複雑なIFは書けない
  • キー比較が前提

「ちょっと条件足そう」というのは即アウトだ。

な)条件足すっていうと、ANDとかを足すってことっすか?

係)そうだ。

WHEN ITEM-ID(IDX) = TARGET-ID AND ITEM-STATUS = "A" みたいに、ついでに状態チェックも入れるなんてのはダメだ。

SEARCH ALLWHEN には、キー項目(ITEM-ID)の純粋な比較しか書けない。

余計なものを混ぜると、それもエラーか予期せぬ動作の元になるぞ。

な)ほえー、一本木太郎すか。略して一太郎っすね。ワープロソフトみたいに、一本気が通ってるのか、融通が利かないのか。悩むところですね。

係)いや全然だな。

な)え!?

速さは正しさを保証しない:SEARCH ALLが嘘をつく瞬間

な)全部SEARCH ALLでよくないすか?

係)よくはないな。

  • SEARCH ALLは条件を満たしてないと間違った答えを“高速で出す”
  • SEARCHは遅いが正しい答えを出す

どっちがマシか、分かるな?

な)そんなの間違うに決まってるじゃないすか!

係)いや、間違うなよ!

いいか、SEARCH ALLはな、“整理整頓できる人間だけに許された近道”だ。

散らかった机で使おうと思うな。まず片付けろ!

な)まさか俺の机見て言ってます?

係)見て言ってるに決まってるだろ!

な)俺の私生活にまで入り込むなんて!プライベートですよ!痴漢ですよ!のび太さんのエッチーですよ!

係)会社の机をプライベートとか言ってんじゃねーよ!

コード例

係)はぁ、次は動く最小コードだ。

SEARCHSEARCH ALLで比較してみろ。

まずはSEARCH(しらみつぶし)

01 ITEM-TABLE.
   05 ITEM-REC OCCURS 5 TIMES
      INDEXED BY IDX.
      10 ITEM-ID   PIC X(3).
      10 ITEM-NAME PIC X(10).

01 TARGET-ID PIC X(3) VALUE "003".

* 初期化
SET IDX TO 1

SEARCH ITEM-REC
    AT END
        DISPLAY "NOT FOUND"  
    WHEN ITEM-ID(IDX) = TARGET-ID
        DISPLAY "FOUND: " ITEM-NAME(IDX)
END-SEARCH

ポイントはこれだ
• 上から 1件ずつ 見る
• 並び順は不要
• INDEXED BYは必須(SEARCHIDXを使う)

次にSEARCH ALL(二分探索)

* 重要:ITEM-ID は昇順に並んでいること!
* 例)"001","002","003","004","005"

01 ITEM-TABLE.
   05 ITEM-REC OCCURS 5 TIMES
      ASCENDING KEY IS ITEM-ID
      INDEXED BY IDX.
      10 ITEM-ID   PIC X(3).
      10 ITEM-NAME PIC X(10).

01 TARGET-ID PIC X(3) VALUE "003".

SEARCH ALL ITEM-REC
    WHEN ITEM-ID(IDX) = TARGET-ID
        DISPLAY "FOUND: " ITEM-NAME(IDX)
END-SEARCH

条件は

  1. キー順にソート済み
  2. INDEXED BYが必須
  3. 比較は 単純なキー比較のみ

あとSEARCH ALLはなASCENDING KEY IS ITEM-IDを書いてないと、そもそも使わせてもらえない前提があるから、忘れるな。

そして、SEARCH ALLSET IDX TO 1 とか、やらなくていい。
二分探索は、真ん中から始めるからな。

よくある事故(見つからないのに“ある”)

* 並びが崩れている例(NG)
* "001","003","002","004","005"

SEARCH ALL ITEM-REC
    AT END
        DISPLAY "NOT FOUND"
    WHEN ITEM-ID(IDX) = TARGET-ID
        DISPLAY "FOUND"
END-SEARCH

並びが崩れていると、見つからないことがあるってことだ。

おむすび

係)結果、どっちを使うかってはなしになるが、

目的使う命令
並び保証なしSEARCH
並び保証ありSEARCH ALL
正確さ最優先SEARCH
速度最優先(条件厳守)SEARCH ALL

SEARCH ALLは「速さ」をくれる代わりに、「並びを保証する責任」を要求してくるからな、その保証ができるなら使えばいい。できないならSEARCHにしとけって話になるな。

な)係長が保証してくれればいいじゃないすか。なるおのミスは私のミスです、なるおは許してやってくださいってコメントに入れときますよ!

「こう言ってるんで許してあげてくださいよ」って課長にみせれば、文句言えないでしょ。

係)なんで俺の責任になってるんだよ!そもそもミスるのを前提にすんな!

係長のワンポイント

SEARCH ALLは「速い命令」じゃない。
並びが正しいと信じ切れる人間だけに許される命令だ。
条件を一つでも破れば、正しいデータでも平然と見逃す。
速さは結果を保証しない、保証するのは準備だけだ。
SEARCH ALLを使う前に、自分が整理整頓できる人間か疑え。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

コメント

コメントする

目次