🧩今日の学び
・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が必須
係)SEARCHもSEARCH ALLもSUBSCRIPTじゃダメだ。インデックスでしか動かないぞ。
「番号で回す」発想は通用しないからな。
な)なんかそこが分かりづらくしてるんじゃないすかね⋯
係)インデックスを使うんだから、先にインデックス処理すると覚えておけばいいだろ。
条件③:比較条件は単純
ただし、
- 複雑な
IFは書けない - キー比較が前提
「ちょっと条件足そう」というのは即アウトだ。
な)条件足すっていうと、ANDとかを足すってことっすか?
係)そうだ。
WHEN ITEM-ID(IDX) = TARGET-ID AND ITEM-STATUS = "A" みたいに、ついでに状態チェックも入れるなんてのはダメだ。
SEARCH ALL の WHEN には、キー項目(ITEM-ID)の純粋な比較しか書けない。
余計なものを混ぜると、それもエラーか予期せぬ動作の元になるぞ。
な)ほえー、一本木太郎すか。略して一太郎っすね。ワープロソフトみたいに、一本気が通ってるのか、融通が利かないのか。悩むところですね。
係)いや全然だな。
な)え!?
速さは正しさを保証しない:SEARCH ALLが嘘をつく瞬間
な)全部SEARCH ALLでよくないすか?
係)よくはないな。
SEARCH ALLは条件を満たしてないと間違った答えを“高速で出す”SEARCHは遅いが正しい答えを出す
どっちがマシか、分かるな?
な)そんなの間違うに決まってるじゃないすか!
係)いや、間違うなよ!
いいか、SEARCH ALLはな、“整理整頓できる人間だけに許された近道”だ。
散らかった机で使おうと思うな。まず片付けろ!
な)まさか俺の机見て言ってます?
係)見て言ってるに決まってるだろ!
な)俺の私生活にまで入り込むなんて!プライベートですよ!痴漢ですよ!のび太さんのエッチーですよ!
係)会社の机をプライベートとか言ってんじゃねーよ!
コード例
係)はぁ、次は動く最小コードだ。
SEARCHとSEARCH 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は必須(SEARCHはIDXを使う)
次に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
条件は
- キー順にソート済み
INDEXED BYが必須- 比較は 単純なキー比較のみ
あとSEARCH ALLはなASCENDING KEY IS ITEM-IDを書いてないと、そもそも使わせてもらえない前提があるから、忘れるな。
そして、SEARCH ALLは SET 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を使う前に、自分が整理整頓できる人間か疑え。

コメント