PDA

View Full Version : IF in COBOL funktioniert nicht immer



Seiten : [1] 2

Daechsle
23-02-09, 13:03
Liebe Experten

In einer Datei gibt es ein 10-stelliges alphanumerisches Feld mit dem Namen PAGUMB, das derzeit in allen ca. 23000 Datensätzen den Wert *NONE enthält. In einem COBOL-Programm werden alle diese Sätze gelesen und für jeden Satz die folgenden Zeilen ausgeführt:
IF NOT(PAGUMB = SPACES OR *NONE)
PERFORM CALL-DOKUMB THRU CALL-DOKUMB-EXIT
END-IF.
CALL-DOKUMB dürfte also in dem Fall nie aufgerufen werden. Das geht auch genau 20044 Mal gut, aber beim 20045. Datensatz wird CALL-DOKUMB aus unerklärlichen Gründen doch aufgerufen!
Das Feld PAGUMB enthält 100%ig wie bei allen anderen Datensätzen auch beim 20045. Mal *NONE und 5 Blanks, also hexadezimal '5CD5D6D5C540404040'. (zumindest wird es im Debugger so angezeigt und auch eine entsprechende Abfrage in SQL bestätigt das)
Auch eine Umformulierung der Abfrage in
IF PAGUMB NOT = SPACES AND PAGUMB NOT = "*NONE"
oder eine nochmalige gleichartige Abfrage im Paragraf CALL-DOKUMB ergeben kein anderes Ergebnis.

Wie kann das möglich sein?

Vielen Dank im Voraus

Fuerchau
23-02-09, 13:57
Ich würde da erst mal per STRDBG den Feldinhalt tatsächlich kontrollieren (Hex).
Also noch mal GENAU prüfen.
Ich glaube nicht an einen Rechenfehler der CPU.

BenderD
23-02-09, 14:06
what about NULL?
D*B


Liebe Experten

In einer Datei gibt es ein 10-stelliges alphanumerisches Feld mit dem Namen PAGUMB, das derzeit in allen ca. 23000 Datensätzen den Wert *NONE enthält. In einem COBOL-Programm werden alle diese Sätze gelesen und für jeden Satz die folgenden Zeilen ausgeführt:
IF NOT(PAGUMB = SPACES OR *NONE)
PERFORM CALL-DOKUMB THRU CALL-DOKUMB-EXIT
END-IF.
CALL-DOKUMB dürfte also in dem Fall nie aufgerufen werden. Das geht auch genau 20044 Mal gut, aber beim 20045. Datensatz wird CALL-DOKUMB aus unerklärlichen Gründen doch aufgerufen!
Das Feld PAGUMB enthält 100%ig wie bei allen anderen Datensätzen auch beim 20045. Mal *NONE und 5 Blanks, also hexadezimal '5CD5D6D5C540404040'. (zumindest wird es im Debugger so angezeigt und auch eine entsprechende Abfrage in SQL bestätigt das)
Auch eine Umformulierung der Abfrage in
IF PAGUMB NOT = SPACES AND PAGUMB NOT = "*NONE"
oder eine nochmalige gleichartige Abfrage im Paragraf CALL-DOKUMB ergeben kein anderes Ergebnis.

Wie kann das möglich sein?

Vielen Dank im Voraus

Bogomil
24-02-09, 10:02
Hallo Daechsle,

wegen der Besonderheiten von COBOL (z.B. Ein-/Ausgabepuffer) kann das Phänomen auch an einer ganz anderen Stelle ausgelöst werden.
Die IF-Anweisung sieht korrekt aus, also muss man sich das gesamte Programm anschauen.

Bogomil

pwrdwnsys
25-02-09, 17:07
Hallo Daechsle,

wegen der Besonderheiten von COBOL (z.B. Ein-/Ausgabepuffer) kann das Phänomen auch an einer ganz anderen Stelle ausgelöst werden.
Die IF-Anweisung sieht korrekt aus, also muss man sich das gesamte Programm anschauen.

Bogomil

Wenn es genau beim letzten Datensatz passiert, scheint es ja eine andere Bedingung im Programm zu geben, welche das Problem auslöst. Heisser Tip: Vielleicht steht irgendwo ein GOTO zu einer Stelle in einer anderen Section, oder aber die Sprungmarke gibt es 2x. Das bringt ein COBOL Programm ins Schleudern, so das es IF-Abfragen oder sogar Section-Grenzen überrennt !

Karsten

Fuerchau
26-02-09, 10:21
Sprungmarke 2x ?
=> Wird vom Compiler bereits abgelehnt
IF-Abfragen überrennen ?
=> nur bei Dezimalfehlern, die ignoriert werden, hier wird aber ein Zeichenvergleich gemacht

Der einzige Grund kann sein, dass ein
READ ... AT END
oder
READ ... INVALID KEY
nicht korrekt mit GOTO oder Status-Feld abgefangen wird und somit der IF auf den vorherigen Inhalt vergleicht.

Pikachu
26-02-09, 10:31
Sprungmarke 2x ?
=> Wird vom Compiler bereits abgelehnt
Unter V5R4 leider noch nicht.

Fuerchau
26-02-09, 11:41
OK, du hast ja Recht (war ich von anderen Compilern eigentlich gewohnt).

Allerdings:
Der Compiler nimmt als Ziel
a) das erste Vorkommen innerhalb der Section
b) das erste Vorkommen in der Quelle

Das führt sicherlich zu Verwirrungen in der Ausführung, wenn man mal schnell einen Paragraph kopiert hat.

Aber nichts ist so schlimm wie:

MYLABEL.
GO TO.
:
MYLABELX.
:
MYLABELY.
:
MYLABELZ.
:
ALTER MYLABEL TO PROCEED TO MYLABELX.
:
:
ALTER MYLABEL TO PROCEED TO MYLABELY.
:
:
ALTER MYLABEL TO PROCEED TO MYLABELZ.
:
:

BenderD
26-02-09, 13:47
dafür gabs früher schon die Referenzhandbücher, zum erschlagen der Programmierer, die sowas machen, (Stichwort: Das Buch als Waffe)

D*B


OK, du hast ja Recht (war ich von anderen Compilern eigentlich gewohnt).

Allerdings:
Der Compiler nimmt als Ziel
a) das erste Vorkommen innerhalb der Section
b) das erste Vorkommen in der Quelle

Das führt sicherlich zu Verwirrungen in der Ausführung, wenn man mal schnell einen Paragraph kopiert hat.

Aber nichts ist so schlimm wie:

MYLABEL.
GO TO.
:
MYLABELX.
:
MYLABELY.
:
MYLABELZ.
:
ALTER MYLABEL TO PROCEED TO MYLABELX.
:
:
ALTER MYLABEL TO PROCEED TO MYLABELY.
:
:
ALTER MYLABEL TO PROCEED TO MYLABELZ.
:
:

pwrdwnsys
26-02-09, 15:58
Sprungmarke 2x ?
=> Wird vom Compiler bereits abgelehnt
IF-Abfragen überrennen ?
=> nur bei Dezimalfehlern, die ignoriert werden, hier wird aber ein Zeichenvergleich gemacht

Der einzige Grund kann sein, dass ein
READ ... AT END
oder
READ ... INVALID KEY
nicht korrekt mit GOTO oder Status-Feld abgefangen wird und somit der IF auf den vorherigen Inhalt vergleicht.

Ungter V5R3 leider noch keine Ablehnung. Aber fatal ist folgendes:

AAA SECTION.

GOTO MARKEXXX.
EXIT.

BBB SECTION.
MARKEXXX.
EXIT.

Führt auch dazu, das das Programm macht was es will. Wenn ich dann einen Trace der ausgeführen Anweisungen anschaue, läuft das Programm zum Anfang und dann (meist) 1x komplett bis zum Ende durch, ohne sich an Sectiongrenzen oder IF's zu stören. Hatte ich schon ein paar mal in diversen Programmen.

Fazit: Wodurch unterscheiden sich gute von schlechten Programmierern ? Die guten denken daran, nach dem Kopieren alle betroffenen Stellen zu ändern!

-K.-