4 cobol
我想知道操纵表的信息.
我遇到一些像下面这样的cobol代码的问题:
01 TABLE-1.
05 STRUCT-1 OCCURS 25 TIMES.
10 VALUE-1 PIC AAA.
10 VALUE-2 PIC 9(5)V999.
05 NUMBER-OF-OCCURS PIC 99.
Run Code Online (Sandbox Code Playgroud)
你如何更新价值观?(当您知道VALUE-1时更新VALUE-2)
如何查找值并添加新值?
非常感谢!
如何查找值/如何更新值
首先,您必须查找要更新的记录(行).这通常通过在表中搜索给定的键值来完成.COBOL提供了两种方法来实现这一点.我建议您首先查看COBOL SEARCH
语句.如果STRUCT-1
记录已排序,您可以使用SEARCH ALL
,否则您必须使用SEARCH
或只编写自己的搜索循环.为了使用这些技术中的任何一种,您需要在程序中的某处声明另一个变量,以用作表中的索引(偏移量)STRUCT-1
.COBOL INDEXED BY
在OCCURS
子句上提供了一个短语
来声明特定于给定表的索引(参见OCCURS)
一旦将索引设置STRUCT-1
为指向要更新的行,您只需MOVE
将该行中的相应变量赋值为例如
移动123.456至VALUE-2(IDX-1)
其中IDX-1是上面提到的索引.请注意,您可以使用整数或索引变量来指定要更新的行号,您不仅限于使用INDEX类型变量.但是,使用INDEX变量通常比其他类型的变量更有效,特别是在使用多维表时,程序会对表进行大量引用.
如何添加新行
首先要认识到STRUCT-1
它恰好包含25行.COBOL没有动态增加或减少这个数字的机制(我听说在下一个ISO COBOL标准中可能会这样 - 但是不要屏住呼吸等待它).从技术上讲,所有25行都可以随时使用.然而,一个常见的约定是将表从一个空"逐渐"变为"完整",一次一行.要使用此约定,您需要分配一个变量来跟踪上次使用的行号(不要忘记在程序启动时将此变量初始化为零).在你的例子中,看起来变量NUMBER-OF-OCCURS
做了这个工作(我没有提到它,但你需要这个变量来绑定上面讨论的SEARCH).
要"添加"一行,只需增加NUMBER-OF-OCCURS
1.注意不要超过表格大小.示例代码可能是:
IF NUMBER-OF-OCCURS < (LENGTH OF TABLE-1 / LENGTH OF STRUCT-1 (1))
ADD +1 TO NUMBER-OF-OCCURS
ELSE
table is full, preform some error/recovery routine
END-IF
Run Code Online (Sandbox Code Playgroud)
上面的代码避免明确使用发生的次数,在TABLE-1
这种情况下,当OCCURS 的数量发生变化时,可以节省许多维护问题.
请参阅底部的注释:这里有一个非常大的Woops - 你有没有抓住它!
现在回到搜索问题.以下代码示例说明了如何继续:
工作 - 存储声明:
01 FOUND-IND PIC X(1).
88 FOUND-YES VALUE 'Y'.
88 FOUND-NO VALUE 'N'.
77 MAX-IDX USAGE IS INDEX.
01 TABLE-1.
05 STRUCT-1 OCCURS 25 TIMES INDEXED BY IDX-1.
10 VALUE-1 PIC AAA.
10 VALUE-2 PIC 9(5)V999.
05 NUMBER-OF-OCCURS PIC 99.
Run Code Online (Sandbox Code Playgroud)
添加了什么:
FOUND-IND
用于指示是否找到了您要查找的行.88级给出了设定/测试的特定值MAX-IDX
用于设置搜索的上限.您可以NUMBER-OF-OCCURS
在上限测试中使用,但这会强制每次测试的数据类型转换效率不高IDX-1
用作表中的索引(偏移量)STRUCT-1
.就个人而言,我会宣布NUMBER-OF-OCCURS
,PIC S9(4) BINARY
但你所拥有的将会奏效.
假设STRUCT-1
未排序并NUMBER-OF-OCCURS
表示当前活动行数,STRUCT-1
这是一个示例,说明SEARCH
在查找值'ABC'时如何编码:
SET FOUND-NO TO TRUE
IF NUMBER-OF-OCCURS > ZERO
SET IDX-1 TO 1
SET MAX-IDX TO NUMBER-OF-OCCURS
SEARCH STRUCT-1
WHEN IDX-1 > MAX-IDX
CONTINUE
WHEN VALUE-1 (IDX-1) = 'ABC'
SET FOUND-YES TO TRUE
END-SEARCH
END-IF
IF FOUND-YES
row found, use IDX-1 to reference the row containing 'ABC'
ELSE
row not found, IDX-1 does not contain a valid index
END-IF
Run Code Online (Sandbox Code Playgroud)
这个怎么运作:
FOUND-NO
为true.IF
确保STRUCT-1
在开始搜索之前至少有一个活动行(将INDEX设置为零是错误的 - 所以你需要防范它).SEARCH
终止时,第一SEARCH WHEN
条是在线北京.这就是为什么CONTINUE
当我们用完行搜索时,可以使用'什么都不'的动词.另一个终止条件(找到您要查找的值)是唯一FOUND-YES
可以设置的地方.SEARCH
完成,试验成功或失败,然后采取相应的行动.一些练习供您研究:
AT END
在SEARCH
声明中编写一个条款?VARYING
在SEARCH
声明中编写一个条款?WHERE
按照我的顺序编写了这些条款?希望这能让你开始走正确的道路.
编辑
在评论中回答您的问题:我们可以使用NUMBER-OF-OCCURS作为搜索索引.答案是肯定的,但您需要实施一些不同的规则.当NUMBER-OF-OCCURS
用作索引时,您不能再使用它来跟踪当前包含有效数据的行数.这意味着您需要另一种机制来识别未使用的行STRUCT-1
.这可以通过初始化未使用的行来实现,这些行具有LOW-VALUE
您永远不会真正想要放入表中的sentinal值(例如).将SEARCH
变为:
SET FOUND-NO TO TRUE
MOVE 1 TO NUMBER-OF-OCCURS
SEARCH STRUCT-1 VARYING NUMBER-OF-OCCURS
WHEN VALUE-1 (NUMBER-OF-OCCURS) = 'ABC'
SET FOUND-YES TO TRUE
END-SEARCH
Run Code Online (Sandbox Code Playgroud)
如果STRUCT-1
您要搜索的值(即.ABC
)不在表中,上面将搜索每一行.作为优化,您可以添加第二个WHEN
子句以在找到sentinal值时终止搜索:
WHEN VALUE-1 (NUMBER-OF-OCCURS) = LOW-VALUE
CONTINUE
Run Code Online (Sandbox Code Playgroud)
以上假设LOW-VALUE
用于标识未使用的行.您也可以
从工作存储中删除IDX-1
,MAX-IDX
因为此解决方案不需要它们.
使用NUMBER-OF-OCCURS
索引还意味着您必须更改搜索空行以插入新值的方式.最简单的方法是使用上面的代码搜索表LOW-VALUE
而不是'ABC'
.如果FOUND-YES
已在搜索结束时设置,那么
NUMBER-OF-OCCURS
是第一个未使用行的索引.如果FOUND-NO
已设置,则表已满.
上面的代码比我最初建议的要简单得多.那么为什么我会给你更
复杂的解决方案呢?更复杂的解决方案更有效,因为它在运行表时会产生更少的内部偏移计算和数据类型转换.它还避免了另外
SEARCH
找到下一个未使用的行.这些效率在您的应用程序中可能并不重要,但如果表很大且经常访问,您应该了解搜索表和强制数据类型转换的性能方面(例如将PIC 99
字段转换为索引引用的成本) .
注意:
我LENGTH OF
在这个例子中使用特殊寄存器来计算表是否已满的原始示例可以在这个示例中使用,但内置假设非常糟糕!LENGTH OF TABLE-1
不仅包括STRUCT-1
桌子,还包括桌子NUMBER-OF-OCCURS
.由于将结果截断为整数值NUMBER-OF-OCCURS
,STRUCT-1
因此长度小于一次出现所以它都可以正常工作.这是代码正确运行的一个很好的例子!要进行正确的计算,您必须将工作存储调整为:
01 TABLE-1.
05 STRUCT-TABLE.
10 STRUCT-1 OCCURS 25 TIMES.
20 VALUE-1 PIC AAA.
20 VALUE-2 PIC 9(5)V999.
05 NUMBER-OF-OCCURS PIC 99.
Run Code Online (Sandbox Code Playgroud)
并且边界计算将变为:
IF NUMBER-OF-OCCURS < (LENGTH OF STRUCT-TABLE / LENGTH OF STRUCT-1 (1))
ADD +1 TO NUMBER-OF-OCCURS
ELSE
table is full, preform some error/recovery routine
END-IF
Run Code Online (Sandbox Code Playgroud)
或者你可以NUMBER-OF-OCCURS
离开TABLE-1
记录定义.
归档时间: |
|
查看次数: |
4122 次 |
最近记录: |