Cobol,Code 65 File Locked

时间:2014-11-29 18:02:07

标签: cobol

我正在尝试访问同一个文件来执行两项特定任务。第一项任务是更新,添加和删除记录。访问必须是随机的。第二个任务是在控制台上显示所有记录。访问必须是顺序的。我从COBOL收到code 65 File locked因为程序试图同时访问同一个文件两次。有没有办法解决这个错误?或者有不同的方法来做到这一点?或者我是否必须编写一个单独的程序来在控制台上显示记录?我被卡住了!

   ENVIRONMENT DIVISION.

   INPUT-OUTPUT SECTION.
   FILE-CONTROL.
       SELECT MAST-FILE ASSIGN TO 'G:\CPSC315-COBOL\COBOLAssignments\P15-5\SALES.IND.TXT'
           ORGANIZATION IS INDEXED
           ACCESS IS RANDOM
           RECORD KEY M-SALESPERSON-NUM.

       SELECT MAST2-FILE ASSIGN TO 'G:\CPSC315-COBOL\COBOLAssignments\P15-5\SALES.IND.TXT'
           ORGANIZATION IS INDEXED
           ACCESS IS SEQUENTIAL
           RECORD KEY M2-SALESPERSON-NUM.

   DATA DIVISION.
   FILE SECTION.
   FD MAST-FILE
       LABEL RECORDS ARE STANDARD.
   01 MAST-RECORD.
       05 M-SALESPERSON-NUM  PIC XXX.
       05 M-CUSTOMER-NAME    PIC X(15).
       05 M-TOTAL-SALES      PIC 9(5)V99.
       05 M-COST-OF-SALES    PIC 9(4)V99.

   FD MAST2-FILE
       LABEL RECORDS ARE STANDARD.
   01 MAST2-RECORD.
       05 M2-SALESPERSON-NUM     PIC X(3).
       05 M2-SALESPERSON-NAME    PIC X(15).
       05 M2-TOTAL-SALES         PIC 9(5)V99.
       05 M2-COST-OF-SALES       PIC 9(4)V99.

   WORKING-STORAGE SECTION.
   01 SALES-DATA.
       05 SALESPERSON-NUM     PIC X(3).
       05 SALESPERSON-NAME    PIC X(15).
       05 TOTAL-SALES         PIC 9(5)V99.
       05 COST-OF-SALES       PIC 9(4)V99.

   01 OUTPUT-RECORD.
       05                      PIC X(1) VALUE SPACES.
       05 O-SALESPERSON-NUM    PIC X(3).
       05                      PIC X(3) VALUE SPACES.
       05 O-SALESPERSON-NAME   PIC X(3).
       05                      PIC X(3) VALUE SPACES.
       05 O-TOTAL-SALES        PIC 9(5)V99.
       05                      PIC X(3) VALUE SPACES.
       05 O-COST-OF-SALES      PIC 9(4)V99.

   01 PROGRAM-DATA-ITEMS.
       05 I-SALESPERSON-NUM       PIC XXX.
       05 WAIT-OK                 PIC X.
       05 CHOICE                  PIC 9 VALUE 0.
       05 READ-OK                 PIC X.
       05 REWRITE-OK              PIC X.
       05 DELETE-OK               PIC X.

   PROCEDURE DIVISION.
   10-MAINLINE.
       OPEN I-O MAST-FILE
       OPEN INPUT MAST2-FILE
       PERFORM 20-PROCESS-LOOP
       CLOSE MAST-FILE
           MAST2-FILE
       STOP RUN.

   20-PROCESS-LOOP.
       PERFORM UNTIL CHOICE = 5
           PERFORM 30-DISPLAY-MENU
           EVALUATE CHOICE
               WHEN 1  
                   PERFORM 40-UPD-SALES
               WHEN 2
                   PERFORM 90-ADD-SALES
               WHEN 3
                   PERFORM 110-DELETE-SALES
               WHEN 4
                   PERFORM 120-DISPLAY-SALES
            END-EVALUATE
        END-PERFORM.

   30-DISPLAY-MENU.
       DISPLAY 'SALES MAINTENANCE SYSTEM'
       DISPLAY ' '
       DISPLAY ' SELECT ONE:'
       DISPLAY ' '
       DISPLAY '   1. UPDATE SALES RECORD'
       DISPLAY '   2. ADD SALES RECORD'
       DISPLAY '   3. DELETE SALES RECORD'
       DISPLAY '   4. DISPLAY SALES RECORD'
       DISPLAY '   5. QUIT'
       DISPLAY ' '
       DISPLAY 'ENTER CHOICE (1 - 5): ' WITH NO ADVANCING
       ACCEPT CHOICE
       PERFORM UNTIL CHOICE >= 1 AND <= 5
           DISPLAY ' '
           DISPLAY 'ERROR: ENTER CHOICE (1 - 5): ' WITH NO ADVANCING
           ACCEPT CHOICE
       END-PERFORM.

   40-UPD-SALES.
       DISPLAY 'UPDATE SALES: ENTER SALESPERSON NUMBER: ' WITH NO ADVANCING
       ACCEPT SALESPERSON-NUM
       MOVE SALESPERSON-NUM TO M-SALESPERSON-NUM
       PERFORM 50-READ-RECORD
       IF READ-OK = 'N'
           DISPLAY 'RECORD DOES NOT EXIST - PRESS ENTER'
           ACCEPT WAIT-OK
       ELSE
           DISPLAY SALES-DATA
           PERFORM 100-INPUT-NEW-RECORD
           PERFORM 60-REWRITE-RECORD
       END-IF.

   50-READ-RECORD.
       MOVE 'Y' TO READ-OK
       READ MAST-FILE INTO SALES-DATA
           INVALID KEY
               MOVE 'N' TO READ-OK
       END-READ.

   60-REWRITE-RECORD.
       REWRITE MAST-RECORD FROM SALES-DATA
           INVALID KEY
               DISPLAY 'REWRITE ERROR: SALESPERSON NUMBER ' SALESPERSON-NUM
               DISPLAY 'PRESS ENTER TO CONTINUE'
               ACCEPT WAIT-OK
       END-REWRITE.

   70-WRITE-RECORD.
       MOVE 'Y' TO REWRITE-OK
       WRITE MAST-RECORD FROM SALES-DATA
           INVALID KEY
               MOVE 'N' TO REWRITE-OK
       END-WRITE
       IF REWRITE-OK = 'N'
           DISPLAY 'WRITE ERROR: SALESPERSON NUMBER ' SALESPERSON-NUM
           DISPLAY 'PRESS ENTER TO CONTINUE'
           ACCEPT WAIT-OK
       END-IF.

   80-DELETE-RECORD.
       MOVE 'Y' TO DELETE-OK
       DELETE MAST-FILE
           INVALID KEY 
               MOVE 'N' TO DELETE-OK
       END-DELETE
       IF REWRITE-OK = 'N'
           DISPLAY 'WRITE ERROR: SALESPERSON NUMBER ' SALESPERSON-NUM
           DISPLAY 'PRESS ENTER TO CONTINUE'
           ACCEPT WAIT-OK
       END-IF.

   90-ADD-SALES.
       DISPLAY 'ADD SALES RECORD: ENTER SALESPERSON NUMBER: ' WITH NO ADVANCING
       ACCEPT SALESPERSON-NUM
       MOVE SALESPERSON-NUM TO M-SALESPERSON-NUM
       PERFORM 50-READ-RECORD
       IF READ-OK = 'Y'
           DISPLAY 'RECORD ALREADY EXISTS - PRESS ENTER'
           ACCEPT WAIT-OK
       ELSE
           PERFORM 100-INPUT-NEW-RECORD
           PERFORM 70-WRITE-RECORD
           IF REWRITE-OK = 'Y'
               DISPLAY 'RECORD ' SALESPERSON-NUM ' ADDED TO FILE'
               DISPLAY 'PRESS ENTER TO CONTINUE'
               ACCEPT WAIT-OK
           END-IF
       END-IF.

   100-INPUT-NEW-RECORD.
       MOVE SALESPERSON-NUM TO M-SALESPERSON-NUM
       DISPLAY '       ENTER SALESPERSON NAME: ' WITH NO ADVANCING
       ACCEPT SALESPERSON-NAME
       DISPLAY '           ENTER TOTAL SALES: ' WITH NO ADVANCING
       ACCEPT TOTAL-SALES
       DISPLAY '               ENTER COST OF SALES: ' WITH NO ADVANCING
       ACCEPT COST-OF-SALES.

   110-DELETE-SALES.
       DISPLAY 'DELETE SALES RECORD: ENTER SALESPERSON NUMBER: ' WITH NO ADVANCING
       ACCEPT SALESPERSON-NUM
       MOVE SALESPERSON-NUM TO M-SALESPERSON-NUM
       PERFORM 50-READ-RECORD
       IF READ-OK = 'N'
           DISPLAY 'RECORD DOES NOT EXIST - PRESS ENTER'
           ACCEPT WAIT-OK
       ELSE
           PERFORM 80-DELETE-RECORD
           IF DELETE-OK = 'Y'
               DISPLAY 'RECORD DELETED - PRESS ENTER'
               ACCEPT WAIT-OK
           END-IF
       END-IF.

   120-DISPLAY-SALES.
       MOVE SALESPERSON-NUM TO M2-SALESPERSON-NUM
       MOVE SALESPERSON-NAME TO M2-SALESPERSON-NAME
       MOVE TOTAL-SALES TO M2-TOTAL-SALES
       MOVE COST-OF-SALES TO M2-COST-OF-SALES
       READ MAST2-FILE
           AT END MOVE HIGH-VALUES TO M2-SALESPERSON-NUM
       END-READ
       PERFORM UNTIL M2-SALESPERSON-NUM = HIGH-VALUES
           MOVE M2-SALESPERSON-NUM TO O-SALESPERSON-NUM
           MOVE M2-SALESPERSON-NAME TO O-SALESPERSON-NAME
           MOVE M2-TOTAL-SALES TO O-TOTAL-SALES
           MOVE M2-COST-OF-SALES TO O-COST-OF-SALES
           DISPLAY OUTPUT-RECORD
           READ MAST2-FILE
               AT END MOVE HIGH-VALUES TO M2-SALESPERSON-NUM
           END-READ
       END-PERFORM.

   end program Program1.

1 个答案:

答案 0 :(得分:2)

当您打开文件I-O时,这意味着您为输入和输出打开它。摆脱你的第二个档案。

要定位文件以显示数据,您可以使用KEY读取,然后阅读READ ... NEXT ...,或者您可以使用START ...然后READ ... NEXT。

始终在ASSIGN中使用文件状态。然后使用文件状态字段告诉COBOL将文件状态置于,以检查以前的IO。将其用于文件结尾(值“10”)。使用88s。然后,您不需要INVALID KEY和AT END,并且与IO关联的所有END语句都可以,因为您没有IO的内置条件。这将简化事情。

你的结构非常适合初学者。刷新看不到PERFORM ...... THRU ....

我建议您尝试在第12列中单个完整停止/期间的效果。然后,您就可以从段落中移动最后一行代码,而不必考虑附加到它的句点/句点(因为它没有附加到它上面)。

使用更多PERFORMs。 OPEN和CLOSE对程序的逻辑并不重要。将它们隐藏在段落中,对它们进行文件状态检查。与READ / WRITE / DELETE以及您最终使用的任何其他IO语句相同。将它们隐藏在您要执行的命名良好的程序中。

考虑一些IF的大小(行数)。将代码放在一个命名良好的过程中,代码可以由人类高级“读取”,只有在需要时才会查看详细信息。

不要,不要,不要,乱用两个文件。不要,不要,不要两次打开同一个文件(我在我的时间里写过一些COBOL程序,而且我从来没有,认为这是一种合理的方式来实现任何目标,更不用说你拥有的简单任务了)。

你可能想要考虑DYNAMIC而不是RANDOM(这就是它的用途)。如果您进行随机访问,则使用RANDOM。您实际上也想要进行顺序访问(查找跳过顺序访问的参考以供进一步讨论)。

SELECT MAST-FILE ASSIGN TO 'G:\CPSC315-COBOL\COBOLAssignments\P15-5\SALES.IND.TXT'
       ORGANIZATION IS INDEXED
       ACCESS IS RANDOMREWRITE-OK = 'N'
       RECORD KEY M-SALESPERSON-NUM
       FILE STATUS IS W-MAST-FILE-STATUS.

...

01  W-MAST-FILE-STATUS                    PIC XX.
    88  W-MAST-FILE-LAST-IO-OK            VALUE "00".
    88  W-MAST-FILE-EOF                   VALUE "10".
    88  W-MAST-FILE-REC-NOT-FOUND         VALUE "23".
    88  W-MAST-FILE-OR-OR-NOT-FOUND       VALUE "00" "23".

...

50-READ-RECORD.
    MOVE 'Y' TO READ-OK
    READ MAST-FILE INTO SALES-DATA
        INVALID KEY
            MOVE 'N' TO READ-OK
    END-READ.

变为:

50-READ-RECORD.
    READ MAST-FILE KEY key-name INTO SALES-DATA
    IF NOT ( W-MAST-FILE-OR-OR-NOT-FOUND ) 
        some code to deal with the pickle, which is nothing to do with 
        business-logic, so hide it away
    END-IF
    .

80-DELETE-RECORD.
    MOVE 'Y' TO DELETE-OK
    DELETE MAST-FILE
        INVALID KEY 
            MOVE 'N' TO DELETE-OK
    END-DELETE
    IF REWRITE-OK = 'N'
        DISPLAY 'WRITE ERROR: SALESPERSON NUMBER ' SALESPERSON-NUM
        DISPLAY 'PRESS ENTER TO CONTINUE'
        ACCEPT WAIT-OK
    END-IF.

变为:

80-DELETE-RECORD.
    DELETE MAST-FILE
    IF NOT W-MAST-FILE-LAST-IO-OK
        DISPLAY 'WRITE ERROR: SALESPERSON NUMBER ' SALESPERSON-NUM
        DISPLAY 'PRESS ENTER TO CONTINUE'
        ACCEPT WAIT-OK
    END-IF
    .

每个IO段都变得自包含,自我验证,并且当您处于业务逻辑中时,FILE STATUS字段自然只具有良好的条件。你可以在这些段落中处理“不可能发生”(但有一天)。

您在其他地方的代码简化了。您的“标志”数量减少了(FILE STATUS字段的值取代了标志的需要)您的IO没有条件部分,所以不需要END范围分隔符。

关于编号段落的提示。在经过充分测试以致您对逻辑结构感到满意之前,请不要这样做。一旦你对此感到满意,重新排列段落,以便段落在之后 。然后把数字打开。然后代码的物理布局代表程序逻辑的结构。

如果你是第一个,你最终会得到你所拥有的情况 - 你有数字,但他们没有推断。 “重新编号”段落比在没有段落编号的情况下添加段落编号要繁琐得多(使用编辑器/实用程序的强大功能来进行编号)。