2016-07-18 19 views
3

Das ist wahrscheinlich eine Anfängerfrage, aber es fällt mir immer noch schwer, herauszufinden, wie man Tabellen in Cobol verwendet.Wie verhindere ich den internen Tabellenüberlauf in Cobol?

Momentan schreibe ich ein einfaches Modul, das von anderen Programmen aufgerufen werden kann. Mein Programm muss eine interne Tabelle nach Daten durchsuchen und falls nicht gefunden, hinzufügen.

Ich habe diese Tabelle: 01 TB-1 OCCURS 10 INDEXED X1. 03 CLIENT-NAME PIC N(30). 03 ORDER-NUMBER PIC 9(06).

Natürlich kann ich die Menge erhöhen AUFTRITT so die Wahrscheinlichkeit von Tabellenüberlauf ab. Beim Testen des Moduls muss ich mich jedoch mit dem Szenario befassen, dass ein weiterer Datensatz hinzugefügt werden muss, der nicht in die Tabelle passt.

Was ist der beste Weg, damit umzugehen? Ich dachte daran, einen ABEND zu verhindern, indem ich eine Fehlermeldung zurück gab.

Um dies zu tun, dachte ich, ich würde ein neues Feld definieren und es als Zähler verwenden. Jedes Mal, wenn mein Modul einen Datensatz hinzufügt, fügt es dem Zähler +1 hinzu. Art wie folgt aus:

IF COUNTER < 10 PERFORM ADD-RECORD ELSE DISPLAY 'INPUT HAS EXCEEDED MAX OF 10 OCCURRENCES' GOBACK END-IF .

ADD-RECORD. MOVE INPUT-CLIENT-NAME TO CLIENT-NAME(X1) IN TB-1. MOVE INPUT-ORDER-NUMBER TO ORDER-NUMBER(X1) IN TB-1. ADD +1 TO COUNTER .

Ist dies ein guter Weg, dies zu tun? Hast du noch andere Ideen? Vielen Dank im Voraus für Ihre Hilfe.

+0

Ich denke, Ihr Code sieht aus wie 'SET X1 UP BY 1 INCLUDE-CLIENT-NAME ZU CLIENT-NAME IN TB-1 (X1) "oder' INPUT-CLIENT-NAME zu CLIENT-NAME IN TB-1 (ZÄHLER) ', nicht wahr? –

+0

Sie haben Recht, es ist das erste. Ich habe vergessen, den Index zu erwähnen, oops! – Lena

+0

Welcher COBOL-Compiler? Welches Betriebssystem? – cschneid

Antwort

3

Die Frage vermisst die Information, welchen Compiler Sie tatsächlich verwenden, deshalb müssen Sie überprüfen, welcher Teil der Antwort für Sie funktioniert.

Die beste Option ist: kein Maximum (COBOL 2014 Feature, nicht sehr wahrscheinlich, dass Ihr Compiler unterstützt diese)

01 TB-1 OCCURS DYNAMIC DEPENDING ON COUNTER 
        INDEXED X1. 
    03 CLIENT-NAME PIC N(30). 
    03 ORDER-NUMBER PIC 9(06). 

Wie Sie bereits einen Zähler Prüfung verwenden, wenn Sie die INDEXED Klausel verwenden (zB für SEARCH), ansonsten fallen lassen und nur den Zähler benutzen.

Auf jedem Fall, dass ich persönlich lieber den Zähler für die Überprüfung der Grenzen, auch in Ihrem Bereich (etwas weniger performant aber sicherer als Ihr Programm abend, wenn etwas falsch ist) zu verwenden:

01 BOUND-ERR. 
     03 FILLER   PIC X(26) VALUE 
      'INPUT HAS EXCEEDED MAX OF '. 
     03 BOUND-MAX  PIC 9(03). 
     03 FILLER   PIC X(11) VALUE 
      'OCCURENCES.'. 
    01 TB-1-COUNT  PIC 9(03) VALUE 0. 
    *> may not work on your compiler... 
    01 TB-1-MAX   AS CONSTANT 10. 
    *> ... then try the level 78 extension: 
    78 TB-1-MAX   VALUE 10.  
    *> if this doesn't work, too, then use REPLACE for the actual bound: 
    REPLACE TB-1-MAX BY 10. 
    01 TB-1 OCCURS  1 TO TB-1-MAX DEPENDING ON TB-1-COUNT 
         INDEXED BY X1. 
     03 CLIENT-NAME PIC N(30). 
     03 ORDER-NUMBER PIC 9(06). 


     IF TB-1-COUNT = TB-1-MAX 
      MOVE TB-1-MAX TO BOUND-MAX 
      DISPLAY BOUND-ERR 
      MOVE 1 TO RETURN-CODE 
      GOBACK 
     END-IF 
     ADD +1 TO TB-1-COUNT 
     SET X1 UP BY 1 
     MOVE INPUT-CLIENT-NAME TO CLIENT-NAME (X1) IN TB-1. 
     MOVE INPUT-ORDER-NUMBER TO ORDER-NUMBER (X1) IN TB-1. 
+0

Eine kurze Überprüfung von Lenas Profil zeigt "Mainframe" als Tag. Aus früheren Fragen wissen wir, dass Lena Enterprise COBOL verwendet. –

1

Der beste Weg, damit umzugehen, unterliegt Interpretation. Schließlich werden Sie ein Limit erreichen und können keinen neuen Eintrag in der Tabelle hinzufügen.

Meine Erfahrung ist, dass die meisten Programmierer eine Obergrenze für die Tabellengröße wählen, die sowohl vernünftig als auch größer ist, als sie erwarten. Z.B. wenn ihnen gesagt wird, dass es nie mehr als 100 Einträge geben wird, machen sie die Tabelle 200 Einträge in der Größe.

Wenn Sie mit IBM Enterprise COBOL v5.2 oder höher können Sie angeben ...

01 TB-1 OCCURS 1 TO UNBOUNDED 
    DEPENDING NB-ITEMS INDEXED X1. 
    03 CLIENT-NAME PIC N(30). 
    03 ORDER-NUMBER PIC 9(06). 

77 NB-ITEMS PIC 9(009) COMP VALUE 10. 

... und Sie sind gut, bis Sie 15.151.516 Einträge getroffen. Dies setzt voraus, dass die Größe eines Vorkommens 66 Bytes beträgt. Das Limit für eine Tabelle UNBOUNDED ist 999.999.998 Bytes; 999999998/66 = 15151515 (und ändern).

Wenn Sie eine frühere Version von IBM Enterprise COBOL verwenden, können Sie entweder eine angemessene Obergrenze für Ihre Tabellengröße auswählen oder Sie können in das Land des dynamisch zuzuweisenden Speichers (über LE Callable Services) einsteigen, was unter nützlich ist bestimmte Umstände aber oft ist Overkill.

+0

Ich habe V5 + noch nicht verwendet, aber Sie benötigen einen OCCURS ON mit der Tabelle, und Sie müssen immer noch Speicher für sie reservieren. Sie müssen nicht den maximalen Speicherplatz zuweisen, sondern nur, was Sie verwenden möchten. Wenn Sie im Flug verlängern müssen, kann es getan werden, aber würde LE die gesamte Tabelle kopieren, also zielen Sie nicht darauf ab, das häufig zu tun. 999,999,998 Bytes ist das * dokumentierte * Limit, aber ich nehme an, das ist ein Fehler (er sagt 'weniger als') in den Dokumenten. –

+0

@BillWoodger korrigiert nach Ihrer ODO-Notiz. Ja, die dynamische Zuweisung wäre ein Aufruf an CEEGTST und nachfolgende CEECZST-Aufrufe, um die Größe bei Bedarf zu ändern, und der letztere kopiert die Daten. Um höflich zu sein, wäre es auch gut, einen Mechanismus zur Verfügung zu stellen, um den Speicher freizugeben, obwohl LE * dies bei der Enklavierung erledigen sollte. – cschneid