SEARCH-Anweisung

Diese Anweisung wird verwendet, um Tabellen zu durchsuchen. Hierbei gibt es verschiedene Methoden. Die einfachste Methode eine Tabelle zu durchsuchen, besteht darin, sich Feld für Feld anzuschauen und den Inhalt mit dem zu suchenden Inhalt zu vergleichen, um dann bei einer Übereinstimmung eine bestimmte Anweisung auszuführen. Diese Art des Vorgehens nennt man:

Sequentielles Suchen
Hierbei wird, wie gesagt die Tabelle Feld für Feld durchsucht um bei Übereinstimmung eine Bedingung auszuführen. Syntax wäre hier:

01 Schuhe.
  05 Schuh OCCURS 20 INDEXED BY Schuh-Index.
    10 Schuh-Gr PIC 99.
    10 Schuh-Farbe PIC X(10).
    10 Schuh-Preis PIC 999V99.

          :
          :
          :

SET Schuh-Index TO 1.
SEARCH Schuh
  WHEN Schuh-Gr (Schuh-Index) = 45 
    DISPLAY Schuh-Preis (Schuh-Index).


Zunächst wurde die Tabelle Schuhe mit Hilfe der OCCURS-Klausel und dem INDEXED BY-Zusatz definiert.
Im Verlauf des Programms wird die definierte Tabelle nach Schuhen der Größe 45 durchsucht. Werden Schuhe der gesuchten Größe gefunden, so wird der Preis der entsprechenden Schuhe angezeigt. Die Abbruchbedingung der Suchschleife efolgt also hinter dem

WHEN-Zusatz
Dieser Zusatz muß mindestens einmal angegeben werden, um der SEARCH-Anweisung 'mitzuteilen' wann die Schleife abzubrechen ist.
Es ist auch möglich, dem Programm anstelle der auszuführenden Anweisung mitzuteilen, daß es bei Eintritt der Bedingung mit der nächsten Zeile im Coding hinter der Suchschleife fortfahren soll. Um dies zu erreichen wird hinter der Bedingung NEXT SENTENCE angegeben. Auf das Beispiel bezogen würde der Syntax lauten:

WHEN Schuh-Gr (Schuh-Index) = 45 NEXT SENTENCE.


Es stellt sich die Frage: "Was geschieht, wenn die hinter WHEN gesetzte Abbruchbedingung nicht erfüllt wird?". Auf das Beispiel bezogen: "Was, wenn keine Schuhe der Größe 45 in der Tabelle vorhanden sind?"
Das Programm wird mit der ersten Zeile, die auf die Suchschleife folgt, fortgesetzt. Oft soll jedoch eine bestimmte Folge eintreten, wenn das gesuchte Element nicht gefunden wird. Daher gibt es den

AT END-Zustz
Dieser Zusatz kann angegeben werden, um bei erfolgloser Suche eine bestimmte Folge eintreten zu lassen. Wird das gesuchte Element also nicht gefunden, so kann hinter AT END angegeben werden, was dann zu geschehen hat. Danach wird das Programm nach der Beendingung der Suchschleife (END SEARCH oder Punkt als Scope-Delimiter) fortgesetzt.
Nehmen wir für unser Beispiel an, daß bei erfolgloser Suche das Unterprogramm 'Bestellung' ausgeführt werden soll, so würde die Suche folgendermaßen codiert:

          :
          :

SET Schuh-Index TO 1.
SEARCH Schuh
  AT END PERFORM Bestellung ,
  WHEN Schuh-Gr (Schuh-Index) = 45 
    DISPLAY Schuh-Preis (Schuh-Index).


Der VARYING-Zusatz
Bei der Suche wird der Index der Tabelle von der SEARCH-Anweisung in der Schrittweite +1 variiert. Man kann diese Variierung auch parallel für andere Indizes von anderen Tabellen oder schlicht für eine Zählvariable durchführen lassen. Dies erreicht man, indem man hinter SEARCH Tabelle den VARYING-Zusatz anbringt.
Nehmen wir an, daß Einzelheiten zu den Schuhen in einer Extra-Tabelle aufgeführt sind und wir auch das Material des entsprechenden Schuhes erfahren möchten, so sähe die Codierung folgendermaßen aus:

01 Schuhe.
  05 Schuh OCCURS 200 INDEXED BY Schuh-Index.
    10 Schuh-Gr PIC 99.
    10 Schuh-Farbe PIC X(10).
    10 Schuh-Preis PIC 999V99.

01 Materialien.
  05 Material OCCURS 200 INDEXED BY Mat-Index.
    10 Sohle PIC X(15).
    10 Innen PIC X(15).
    10 Obermat PIC X(15).

          :
          :
          :

SET Schuh-Index TO 1.
SEARCH Schuh VARYING Mat-Index
  AT END PERFORM Bestellung
  WHEN Schuh-Gr (Schuh-Index) = 45 
    DISPLAY Schuh-Preis (Schuh-Index), Obermat (Mat-Index).


Um eine entsprechende Zählvariable 'mitvariieren' zu lassen, wird einfach der entsprechende Variablenname hinter VARYING angegeben.

Binäres Suchen oder Halbierungsmethode
Nehmen wir an, wir hätten eine Tabelle, in der die Zahlen von 1 bis 100 hintereinander abgelegt sind. In dieser Tabelle wollen wir nach der Zahl 87 suchen. Nach der Methode des sequentiellen Suchens müßten wir also 86 Zahlen mit der gesuchten Zahl vergleichen, ehe wir einen Treffer verbuchen könnten.
Nach der Halbierungsmethode geht man so vor, daß man zunächst das mittlere Element der Tabelle ermittelt. Dies geschieht nach der Formel: (erster Tabellenindex + letzter Tabellenindex) / 2.
Dieses mittlere Element wird nun mit dem gesuchten verglichen. Entspricht das gesuchte dem vorgefundenen Element ist die Suchbedingung erfüllt und die Suche wird beendet.
Liegt keine Übereinstimmung vor, so wird geprüft, ob das gesuchte Element größer oder kleiner ist als das vorgefundene. In unserem Fall (87) wäre das gesuchte Feld also größer als das vorgefundene. Nun würde wiederum die Mitte der oberen Hälfte (50 + 100) / 2 = 75 ermittelt. Hier wird wieder verglichen. Das gesuchte Element wäre hier wiederum größer als das vorgefundene - also wird der Algorythmus fortgeführt. Beim nächsten Vergleich wäre somit der gesuchte Inhalt gefunden.
Das Verhältnis der Anzahl an durchgeführten Vergleichen zwischen sequentiellem und binärem Suchen liegt in diesem Fall also bei 29:1(87 Vergleiche - 3 Vergleiche). Dies erklärt, warum das binäre Suchen gerade in umfangreichen Tabellen wesentlich schneller geht.
Voraussetzung für eine derartige Suche ist zunächst, daß die Tabelle sortiert ist. Dies wird mit der SORT-Anweisung bewerkstelligt.

Der ASCENDING/DESCENDING KEY-Zusatz
Da eine Tabelle auf- oder absteigend sortiert sein kann, muß in der OCCURS-Klausel angegeben werden, welche Art der Sortierung für die entsprechende Tabelle gilt. Für die Tabelle 'Schuhe' sähe die Definition dann bei aufsteigender Sortierung folgendermaßen aus:

01 Schuhe.
  05 Schuh OCCURS 200
           ASCENDING KEY Schuh-Gr
           INDEXED BY Schuh-Index.
    10 Schuh-Gr PIC 99.
    10 Schuh-Farbe PIC X(10).
    10 Schuh-Preis PIC 999V99.


Hinter den ASCENDING/DESCENDING-Zusatz wird also das Schlüsselfeld spezifiziert, nach dem die Tabelle sortiert sein soll. Es findet dabei keine Überprüfung von Cobol-Seite statt, ob die Tabelle tatsächlich so sortiert ist. Daher heißt es bei Habib* an der Stelle auch so treffend: "... dies (gemeint ist die tatsächliche Sortierung) liegt ausschließlich in der Verantwortung des Programmierers".
Natürlich kann eine Tabelle auch nach mehreren Sortierbegriffen aufsteigend (ASCENDING) und/oder absteigend (DESCENDING) sortiert sein.

Die SEARCH ALL-Anweisung
Diese Anweisung wird verwendet, wenn man Tabellen nach der Halbierungsmethode (binäres Suchen) durchsuchen will. Es gelten prinzipiell die Regeln der SEARCH-Anweisung (s.o.). Es gibt jedoch einige Einschränkungen in Bezug auf den WHEN-Zusatz:
- Es darf zunächst nur verglichen werden, ob das zu suchende und das Vergleichsfeld gleich (=) sind.
- In der gesetzten Bedingung darf die logische Verknüpfung AND aber nicht OR verwendet werden.
- Wird ein auf der Stufennummer 88 definierter Bedingungsname angegeben, so darf dieser nur einen einzigen Wert haben.
- In der Vergleichsbedingung muß einer der Vergleichsoperatoren der Sortierbegriff sein, der im KEY-Zusatz der Tabellendefinition enthalten sein muß.
Da der Index beim binären Suchen ständig automatisch innerhalb der Tabellengrenzen verändert wird (eb gemäß den Regeln des binären Suchens), braucht er nicht auf einen Anfangswert gesetzt zu werden.

Wenn wir den oben aufgeführten Suchalgorythmus auf binäres Suchen umstellen würden, so sähe das Ergebnis folgendermaßen aus:

01 Schuhe.
  05 Schuh OCCURS 200 INDEXED BY Schuh-Index.
    10 Schuh-Gr PIC 99.
    10 Schuh-Farbe PIC X(10).
    10 Schuh-Preis PIC 999V99.

          :
          :
          :

SEARCH ALL Schuh 
  AT END PERFORM Bestellung
  WHEN Schuh-Gr (Schuh-Index) = 45 
    DISPLAY Schuh-Preis (Schuh-Index).




*Raouf Habib; COBOL/2 Workbench 2. Aufl. 1995; IWT Verlag GmbH

...