COBOL - EXIT 语句奇怪的行为

COBOL - EXIT statement weird behavior

我在使用 COBOL 编码时遇到了一个奇怪的问题。

我编写了这些执行语句:

        PERFORM 000-INITIAL
           THRU 000-INITIAL-EXIT.

        PERFORM 100-MAIN-PROCESS
           THRU 100-MAIN-PROCESS-EXIT
          UNTIL END-OF-FILE.

        PERFORM 900-END-PGM
           THRU 900-END-PGM-EXIT.

然后是第 100-MAIN-PROCESS 段和紧接 100-MAIN-PROCESS-EXIT 之后的下一段中的句子:

    100-MAIN-PROCESS.

        MOVE  WS-ACCOUNT-NO         TO  IB-ROUTE-ACCT-NUM.

        CALL IBRTEDBS               USING IB-ROUTE-PARAMETERS.

        MOVE  014                   TO  KEY-DDACCT00-BANK-NO.
        MOVE  'D'                   TO  KEY-DDACCT00-APP-CODE.
        MOVE  WS-ACCOUNT-NO         TO  KEY-DDACCT00-ACCT-NO.

        PERFORM  920-GU-ACCT
           THRU  920-EXIT.

        IF NOT SUCCESSFUL-STATUS
           MOVE 999999              TO SDCR-GENERAL-BRANCH-1
        ELSE
           MOVE DD-ACCT-BRANCH      TO SDCR-GENERAL-BRANCH-1.

        PERFORM 200-WRITE-DATA
           THRU 200-WRITE-DATA-EXIT.

        READ IN-FILE AT END MOVE 'Y' TO SW-EOF.

    100-MAIN-PROCESS-EXIT.
        EXIT.

   *----------------------------------------------------------------*

    200-WRITE-DATA.                               

        INITIALIZE DASDCR-REC.
        MOVE 'L'                    TO  INPUT-LOG-TYPE.
        MOVE 'D'                    TO  INPUT-APP-CODE.
        MOVE 014                    TO  INPUT-BANK-NO.

如果 END-OF-FILE 为真 (SW-EOF = 'Y'),则循环应该已经结束并且该过程应该继续到段落 900-END-PGM。问题是,该过程没有这样做,而是继续进行到 200-WRITE-DATA。就好像它在读完EXIT语句后执行了NEXT SENTENCE。 有人知道为什么会这样吗?有什么解决办法吗?

更新: 更正了句子READ IN-FILE,复制了错误的代码。 GO TO 900-END-PGM 只是我使用的临时修复程序,因此程序可以 运行 正确。 我也确定这个问题,因为我已经使用调试工具逐行观察了这个运行。

这里是完整的代码:

    PROCEDURE  DIVISION.

        PERFORM 000-INITIAL
           THRU 000-INITIAL-EXIT.

        PERFORM 100-MAIN-PROCESS
           THRU 100-MAIN-PROCESS-EXIT
          UNTIL END-OF-FILE.

        PERFORM 900-END-PGM
           THRU 900-END-PGM-EXIT.

   *----------------------------------------------------------------*

    000-INITIAL.

        ENTRY  'DLITCBL'            USING  PCB-IO-TERM
                                           PCB-DDACCAPR
                                           PCB-DDACCJFC
                                           PCB-DDACCCPR
                                           PCB-DDACCDPR
                                           PCB-DDACCEPR
                                           PCB-DDACCFPR
                                           PCB-DDACCGPR
                                           PCB-DDACCHPR
                                           PCB-DDACCIPR
                                           PCB-DDACCJPR
                                           PCB-DDACCKPR
                                           PCB-DDACCLPR
                                           PCB-DDACCMPR
                                           PCB-DDACCNPR.

        OPEN INPUT IN-FILE
        IF NOT FILE-SUCCESSFUL-STATUS
           DISPLAY 'OPEN INPUT FILE QSAM IN-FILE ERROR: '
           WS-FILE-STATUS
           GO TO 000-INITIAL-EXIT.

        OPEN OUTPUT OUT-FILE
        IF NOT FILE-SUCCESSFUL-STATUS
           DISPLAY 'OPEN INPUT FILE QSAM OUT-FILE ERROR: '
           WS-FILE-STATUS
           GO TO 000-INITIAL-EXIT.

        READ IN-FILE AT END MOVE 'Y' TO SW-EOF.

    000-INITIAL-EXIT.
        EXIT.

   *----------------------------------------------------------------*

    100-MAIN-PROCESS.

        MOVE  IN-DDA                TO  IB-ROUTE-ACCT-NUM.

        CALL IBRTEDBS               USING IB-ROUTE-PARAMETERS.

        MOVE  014                   TO  KEY-DDACCT00-BANK-NO.
        MOVE  'D'                   TO  KEY-DDACCT00-APP-CODE.
        MOVE  IN-DDA                TO  KEY-DDACCT00-ACCT-NO.

        PERFORM  920-GU-ACCT
           THRU  920-EXIT.

        IF NOT SUCCESSFUL-STATUS
           MOVE 999999              TO SDCR-GENERAL-BRANCH-1
        ELSE
           MOVE DD-ACCT-BRANCH      TO SDCR-GENERAL-BRANCH-1.

        PERFORM 200-WRITE-DATA
           THRU 200-WRITE-DATA-EXIT.

        READ IN-FILE AT END MOVE 'Y' TO SW-EOF.

    100-MAIN-PROCESS-EXIT.
        EXIT.

   *----------------------------------------------------------------*

    200-WRITE-DATA.

        INITIALIZE DASDCR-REC.
        MOVE 'L'                    TO  INPUT-LOG-TYPE.
        MOVE 'D'                    TO  INPUT-APP-CODE.
        MOVE 014                    TO  INPUT-BANK-NO.
        MOVE IN-DDA                 TO  INPUT-ACCOUNT-NO.
        MOVE 'B998001P'             TO  INPUT-USER-ID.
        MOVE 624                    TO  SDCR-TRANS-CODE.
        MOVE 650                    TO  SDCR-SOURCE.
        MOVE 0                      TO  SDCR-CONTROL.
        MOVE IN-ORG-BAL             TO  SDCR-AMOUNT.
        MOVE 0                      TO  SDCR-SERIAL-NUMBER.
        MOVE IN-BRANCH              TO  SDCR-BRANCH-NO.
        MOVE '8860'                 TO  SDCR-THP-TXN.

        MOVE 'CBG:'                 TO  WS-GNR-TRLR-1A.
        MOVE IN-BRANCH              TO  WS-GNR-TRLR-1B.
        MOVE 'INV-'                 TO  WS-GNR-TRLR-2A
        MOVE SPACES                 TO  WS-GNR-TRLR-2B.
        MOVE 'DUE-'                 TO  WS-GNR-TRLR-3A.
        MOVE ZEROES                 TO  WS-GNR-TRLR-3B.
        MOVE IN-ACCT-NO             TO  WS-GNR-TRLR-4A.
        MOVE IN-NOTE-NO             TO  WS-GNR-TRLR-4B.
        MOVE WS-GNR-TRLR-1          TO  SDCR-GENERAL-TRLR-1.
        MOVE WS-GNR-TRLR-2          TO  SDCR-GENERAL-TRLR-2.
        MOVE WS-GNR-TRLR-3          TO  SDCR-GENERAL-TRLR-3.
        MOVE WS-GNR-TRLR-4          TO  SDCR-GENERAL-TRLR-4.
        MOVE SPACES                 TO  SDCR-GENERAL-TRLR-5.
        MOVE 'ID'                   TO  CTR1-PREFIX.
        MOVE WSS-CTR-ID             TO  SDCR-GENERAL-TRLR-5.
        MOVE '001'                  TO  SDCR-GENERAL-ID.
        MOVE 'Y'                    TO  SDCR-GENERAL-TTL-IND.
        MOVE 'GNR'                  TO  SDCR-GENERAL-FIX.
        MOVE '0785'                 TO  SDCR-GENERAL-NOBOOK.

        WRITE OUT-REC FROM DASDCR-REC.

        IF NOT ACCT-STATUS-OK
           ADD  1 TO  CTR3
           DISPLAY 'WRITE QSAM FILE LNSDCR02 : '
           DISPLAY 'WRITE/' IN-DDA '/ERROR/ ' STATUS-FILE1.

        ADD  1                      TO  CTR2.

    200-WRITE-DATA-EXIT.
        EXIT.

   *----------------------------------------------------------------*

    920-GU-ACCT.

        GO  TO  920-GU-DDACCT00-DDACCAPR
                920-GU-DDACCT00-DDACCJFC
                920-GU-DDACCT00-DDACCCPR
                920-GU-DDACCT00-DDACCDPR
                920-GU-DDACCT00-DDACCEPR
                920-GU-DDACCT00-DDACCFPR
                920-GU-DDACCT00-DDACCGPR
                920-GU-DDACCT00-DDACCHPR
                920-GU-DDACCT00-DDACCIPR
                920-GU-DDACCT00-DDACCJPR
                920-GU-DDACCT00-DDACCKPR
                920-GU-DDACCT00-DDACCLPR
                920-GU-DDACCT00-DDACCMPR
                920-GU-DDACCT00-DDACCNPR
        DEPENDING  ON  IB-ROUTE-PROCESS-CTL.

   *----------------------------------------------------------------*

    920-GU-DDACCT00-DDACCAPR.

        CALL  'CBLTDLI'             USING  GU-FUNC
                                           PCB-DDACCAPR
                                           DDACCT00
                                           SSA-DDACCT00.

        MOVE  STC-DDACCAPR          TO  WS-RETURN-STATUS.


        GO TO 920-GU-DDACCT00-CHECK-STATUS.

   *----------------------------------------------------------------*

    920-GU-DDACCT00-DDACCJFC.

        CALL  'CBLTDLI'             USING  GU-FUNC
                                           PCB-DDACCJFC
                                           DDACCT00
                                           SSA-DDACCT00.

        MOVE  STC-DDACCJFC          TO  WS-RETURN-STATUS.


        GO TO 920-GU-DDACCT00-CHECK-STATUS.

   *----------------------------------------------------------------*

    920-GU-DDACCT00-DDACCCPR.

        CALL  'CBLTDLI'             USING  GU-FUNC
                                           PCB-DDACCCPR
                                           DDACCT00
                                           SSA-DDACCT00.

        MOVE  STC-DDACCCPR          TO  WS-RETURN-STATUS.


        GO TO 920-GU-DDACCT00-CHECK-STATUS.

   *----------------------------------------------------------------*

    920-GU-DDACCT00-DDACCDPR.

        CALL  'CBLTDLI'             USING  GU-FUNC
                                           PCB-DDACCDPR
                                           DDACCT00
                                           SSA-DDACCT00.

        MOVE  STC-DDACCDPR          TO  WS-RETURN-STATUS.


        GO TO 920-GU-DDACCT00-CHECK-STATUS.

   *----------------------------------------------------------------*

    920-GU-DDACCT00-DDACCEPR.

        CALL  'CBLTDLI'             USING  GU-FUNC
                                           PCB-DDACCEPR
                                           DDACCT00
                                           SSA-DDACCT00.

        MOVE  STC-DDACCEPR          TO  WS-RETURN-STATUS.


        GO TO 920-GU-DDACCT00-CHECK-STATUS.

   *----------------------------------------------------------------*

    920-GU-DDACCT00-DDACCFPR.

        CALL  'CBLTDLI'             USING  GU-FUNC
                                           PCB-DDACCFPR
                                           DDACCT00
                                           SSA-DDACCT00.

        MOVE  STC-DDACCFPR          TO  WS-RETURN-STATUS.


        GO TO 920-GU-DDACCT00-CHECK-STATUS.

   *----------------------------------------------------------------*

    920-GU-DDACCT00-DDACCGPR.

        CALL  'CBLTDLI'             USING  GU-FUNC
                                           PCB-DDACCGPR
                                           DDACCT00
                                           SSA-DDACCT00.

        MOVE  STC-DDACCGPR          TO  WS-RETURN-STATUS.


        GO TO 920-GU-DDACCT00-CHECK-STATUS.

   *----------------------------------------------------------------*

    920-GU-DDACCT00-DDACCHPR.

        CALL  'CBLTDLI'             USING  GU-FUNC
                                           PCB-DDACCHPR
                                           DDACCT00
                                           SSA-DDACCT00.

        MOVE  STC-DDACCHPR          TO  WS-RETURN-STATUS.

        GO TO 920-GU-DDACCT00-CHECK-STATUS.

   *----------------------------------------------------------------*

    920-GU-DDACCT00-DDACCIPR.

        CALL  'CBLTDLI'             USING  GU-FUNC
                                           PCB-DDACCIPR
                                           DDACCT00
                                           SSA-DDACCT00.

        MOVE  STC-DDACCIPR          TO  WS-RETURN-STATUS.

        GO TO 920-GU-DDACCT00-CHECK-STATUS.

   *----------------------------------------------------------------*

    920-GU-DDACCT00-DDACCJPR.

        CALL  'CBLTDLI'             USING  GU-FUNC
                                           PCB-DDACCJPR
                                           DDACCT00
                                           SSA-DDACCT00.

        MOVE  STC-DDACCJPR          TO  WS-RETURN-STATUS.

        GO TO 920-GU-DDACCT00-CHECK-STATUS.

   *----------------------------------------------------------------*

    920-GU-DDACCT00-DDACCKPR.

        CALL  'CBLTDLI'             USING  GU-FUNC
                                           PCB-DDACCKPR
                                           DDACCT00
                                           SSA-DDACCT00.

        MOVE  STC-DDACCKPR          TO  WS-RETURN-STATUS.

        GO TO 920-GU-DDACCT00-CHECK-STATUS.

   *----------------------------------------------------------------*

    920-GU-DDACCT00-DDACCLPR.

        CALL  'CBLTDLI'             USING  GU-FUNC
                                           PCB-DDACCLPR
                                           DDACCT00
                                           SSA-DDACCT00.

        MOVE  STC-DDACCLPR          TO  WS-RETURN-STATUS.

        GO TO 920-GU-DDACCT00-CHECK-STATUS.

   *----------------------------------------------------------------*

    920-GU-DDACCT00-DDACCMPR.

        CALL  'CBLTDLI'             USING  GU-FUNC
                                           PCB-DDACCMPR
                                           DDACCT00
                                           SSA-DDACCT00.

        MOVE  STC-DDACCMPR          TO  WS-RETURN-STATUS.

        GO TO 920-GU-DDACCT00-CHECK-STATUS.

   *----------------------------------------------------------------*

    920-GU-DDACCT00-DDACCNPR.

        CALL  'CBLTDLI'             USING  GU-FUNC
                                           PCB-DDACCNPR
                                           DDACCT00
                                           SSA-DDACCT00.

        MOVE  STC-DDACCNPR          TO  WS-RETURN-STATUS.

        GO TO 920-GU-DDACCT00-CHECK-STATUS.

   *----------------------------------------------------------------*

    920-GU-DDACCT00-CHECK-STATUS.

        IF DATA-NOT-FOUND
           DISPLAY IN-DDA '---DDACCT ZERO RECORD NOT FOUND...'
           GO TO 920-EXIT.

        IF  NOT  SUCCESSFUL-STATUS
            PERFORM 999-ABEND
               THRU 999-ABEND-EXIT.

    920-EXIT.
        EXIT.

   *----------------------------------------------------------------*

    999-ABEND.

        MOVE  ABEND-MESS(WS-ABEND-SUB)
                                    TO ABEND-TEXT-MESS.
        DISPLAY  ABEND-TEXT.

        CALL  'IBABNDBS'.

    999-ABEND-EXIT.
        EXIT.

   *----------------------------------------------------------------*

    900-END-PGM.

        DISPLAY  'TOTAL READ                  : '  CTR1.
        DISPLAY  'TOTAL WRITE-SUKSES          : '  CTR2.
        DISPLAY  'TOTAL WRITE-FAILED LNSDCR02 : '  CTR3.

        CLOSE IN-FILE
        IF NOT FILE-SUCCESSFUL-STATUS
           DISPLAY 'CLOSE FILE QSAM IN-FILE ERROR: '
           WS-FILE-STATUS.

        CLOSE OUT-FILE
        IF NOT FILE-SUCCESSFUL-STATUS
           DISPLAY 'CLOSE FILE QSAM OUT-FILE ERROR: '
           WS-FILE-STATUS.

        GOBACK.

    900-END-PGM-EXIT.
        EXIT.

这可能是也可能不是原因(我们不能说没有检查代码的可能性),但您的程序中断了程序流程,因为:

    READ IN-FILE AT END MOVE 'Y' TO SW-EOF
                        GO TO 900-END-PGM.

100-MAIN-PROCESS-EXIT.
    EXIT.

如果到达文件末尾,则设置 END-OF-FILE(至少我可以假设这一点,无需检查代码,如果使用 SET END-OF-FILE TO TRUE 而不是 [=,这可能更干净13=] btw) 然后 GO TO 900-END-PGM.。 您永远不会到达段落 100-MAIN-PROCESS-EXIT.,因此您的主循环仍将处于活动状态。

900-END-PGM是什么样子的?代码放在哪里(都是 "below" 你的主要 PERFORM UNTIL 吗?

附加说明:EXIT 语句是空操作,您可以将其替换为 CONTINUE 以更清楚地了解它的实际作用。 "EXIT" 只是一种评论 "somewhere we use PERFORM THRU and end here".

感谢@SimonSobisch,通过将 ENTRY 语句移出 PERFORM 000-INITIAL 解决了这个问题,如下所示:

   PROCEDURE  DIVISION.

       ENTRY  'DLITCBL'            USING  PCB-IO-TERM
                                          PCB-DDACCAPR
                                          PCB-DDACCJFC
                                          PCB-DDACCCPR
                                          PCB-DDACCDPR
                                          PCB-DDACCEPR
                                          PCB-DDACCFPR
                                          PCB-DDACCGPR
                                          PCB-DDACCHPR
                                          PCB-DDACCIPR
                                          PCB-DDACCJPR
                                          PCB-DDACCKPR
                                          PCB-DDACCLPR
                                          PCB-DDACCMPR
                                          PCB-DDACCNPR.

       PERFORM 000-INITIAL
          THRU 000-INITIAL-EXIT.

       PERFORM 100-MAIN-PROCESS
          THRU 100-MAIN-PROCESS-EXIT
         UNTIL END-OF-FILE.

       PERFORM 900-END-PGM
          THRU 900-END-PGM-EXIT.

  *----------------------------------------------------------------*

   000-INITIAL.

       OPEN INPUT IN-FILE
       IF NOT FILE-SUCCESSFUL-STATUS
          DISPLAY 'OPEN INPUT FILE QSAM IN-FILE ERROR: '
          WS-FILE-STATUS
          GO TO 000-INITIAL-EXIT.

       OPEN OUTPUT OUT-FILE
       IF NOT FILE-SUCCESSFUL-STATUS
          DISPLAY 'OPEN INPUT FILE QSAM OUT-FILE ERROR: '
          WS-FILE-STATUS
          GO TO 000-INITIAL-EXIT.

       READ IN-FILE AT END MOVE 'Y' TO SW-EOF.

   000-INITIAL-EXIT.
       EXIT.