如何防止COBOL中的内部表溢出?

问题描述 投票:4回答:3

这可能是一个新手问题,但我仍然很难确定如何在COBOL中使用表格。

目前我正在编写一个可以被其他程序调用的简单模块。我的程序必须在内部表中搜索数据,如果没有找到,则添加到它。

我有这张桌子:

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

当然,我可以增加OCCURS的数量,以便表溢出的可能性降低。但是,在测试模块时,我必须处理一个场景,即要添加的一个记录不适合表中。

处理这个问题的最佳方法是什么?我想通过回复错误消息来防止ABEND。

为此,我想我会定义一个新字段并将其用作计数器。所以基本上,每次我的模块添加记录时,它都会向计数器添加+1。有点像这样:

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
    .

这是一个很好的方法吗?你还有其他建议吗?在此先感谢您的帮助。

cobol mainframe
3个回答
4
投票

问题错过了您实际使用的编译器的信息,因此您必须检查答案的哪个部分适合您。

最好的选择是:没有最大值(COBOL 2014功能,您的编译器不太可能支持此功能)

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

因为您已经使用了计数器检查是否使用了INDEXED子句(例如SEARCH),否则请将其删除并仅使用计数器。

在任何情况下,我个人更喜欢使用计数器进行边界检查,即使在你的范围内(性能稍差但更安全,因为如果出现问题你的程序会异常终止):

    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.

1
投票

解决这个问题的最佳方法是解释。最终,您将达到限制,并且无法在表格中添加新条目。

我的经验是,大多数程序员选择表大小的上限,这是合理的,并且比他们预期的要大。例如。当他们被告知永远不会超过100个条目时,他们会使表格大小为200个条目。

如果您使用的是IBM Enterprise COBOL v5.2或更高版本,则可以指定...

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.

...你很好,直到你达到15,151,516个条目。这假设一次出现的大小是66个字节。 UNBOUNDED表的限制是999,999,998字节; 999999998/66 = 15151515(并更改)。

如果您使用的是早期版本的IBM Enterprise COBOL,您可以为您的表大小选择合理的上限,或者您可以冒险进入动态分配存储的范围(通过LE可调用服务),这在某些情况下很有用,但通常是矫枉过正。


0
投票

不要使用幻数固定表的大小,而是使用REPLACE语句。

REPLACE ==TB-1-TABLE-SIZE== BY ==10==.
01 TB-1 OCCURS TB-1-TABLE-SIZE INDEXED X1.
   03 CLIENT-NAME    PIC N(30).
   03 ORDER-NUMBER   PIC 9(06).
IF COUNTER < TB-1-TABLE-SIZE
     PERFORM ADD-RECORD
ELSE DISPLAY 'INPUT HAS EXCEEDED MAX OF ' TB-1-TABLE-SIZE ' OCCURRENCES'
     GOBACK 
END-IF
.

使用REPLACE可以在一个地方进行任何更改。

2002年,可以使用CONSTANT

01 TB-1-TABLE-SIZE CONSTANT 20.
© www.soinside.com 2019 - 2024. All rights reserved.