COBOL嵌套DEPENDING ON子句数据覆盖问题及XML生成求助
COBOL嵌套DEPENDING ON子句数据覆盖问题解决方案
问题背景
当前使用COBOL定义了包含嵌套可变数组的表结构,Person为顶层可变数组,每个Person下包含paymentA、paymentB子结构,子结构内的可变数组依赖全局计数器。执行代码时,第一个Person实例数据填充正常,但从第二个Person实例开始,操作cnt-A-subsidy等全局计数器会覆盖第一个实例的子数据。
原表结构
.... .... 20 Person occurs 1 to 20 depending on cnt-person. 25 Id pic x(05). 25 Name pic x(10). 25 Address pic x(20). 25 paymentA. 30 Subsidydata. 35 Subsidy occurs 0 to 10 depending on cnt-A-subsidy. 40 Begin pic x(02). 40 End pic x(02). 40 Amount pic x(03). 30 Provdata. 35 Provision occurs 0 to 10 depending on count-A-provis. 40 Begin pic x(02). 40 End pic x(02). 40 Amount pic x(03). 25 paymentB. 30 Subsidydata. 35 Subsidy occurs 0 to 10 depending on count-B-subsidy. 40 Begin pic x(02). 40 End pic x(02). 40 Amount pic x(03). 30 Provdata. 35 Provision occurs 0 to 10 depending on count-B-provis. 40 Begin pic x(02). 40 End pic x(02). 40 Amount pic x(03). 01 count-details. 05 cnt-person pic S9(04) binary. 05 cnt-A-subsidy pic S9(04) binary. 05 count-A-provis pic S9(04) binary. 05 count-B-subsidy pic S9(04) binary. 05 count-B-provis pic S9(04) binary. .... ....
原代码逻辑
In a loop reading db2 table...person add 1 to cnt-person. move spaces to Person(cnt-person). move table-idnr to Id of Person(cnt-person). move table-addr to address of Person(cnt-person). then again reading another table in loop...fetch records and then, if subsidydataA. add 1 to cnt-A-subsidy. move table-begin to Begin of subsidy of subsidydata of paymentA (cnt-person,cnt-A-subsidy). ... ... end. if ProvdataA. add 1 to cnt-A-provis. move table-begin to Begin of Provision of provdata of paymentA (cnt-person,cnt-A-provis). ... ... end. if subsidydataB. add 1 to cnt-B-subsidy. move table-begin to Begin of subsidy of subsidydata of paymentB (cnt-person,cnt-B-subsidy). ... ... end. if ProvdataB. add 1 to cnt-B-provis. move table-begin to Begin of Provision of provdata of paymentB (cnt-person,cnt-B-provis). ... ... end. ..... then ended......
问题根源
全局计数器cnt-A-subsidy、count-A-provis等不属于单个Person实例,所有Person共享同一组计数器。处理第二个Person时,递增全局计数器会指向第一个Person实例的子数组存储位置,导致数据覆盖。
解决方案
1. 修改表结构:将计数器移至Person实例内部
把原全局计数器从count-details中移除,添加到Person结构内部,使每个Person拥有独立的子数组计数器,同时更新DEPENDING ON子句的引用目标:
.... .... 20 Person occurs 1 to 20 depending on cnt-person. 25 Id pic x(05). 25 Name pic x(10). 25 Address pic x(20). 25 person-counters. 30 cnt-A-subsidy pic S9(04) binary. 30 count-A-provis pic S9(04) binary. 30 count-B-subsidy pic S9(04) binary. 30 count-B-provis pic S9(04) binary. 25 paymentA. 30 Subsidydata. 35 Subsidy occurs 0 to 10 depending on cnt-A-subsidy of Person(cnt-person). 40 Begin pic x(02). 40 End pic x(02). 40 Amount pic x(03). 30 Provdata. 35 Provision occurs 0 to 10 depending on count-A-provis of Person(cnt-person). 40 Begin pic x(02). 40 End pic x(02). 40 Amount pic x(03). 25 paymentB. 30 Subsidydata. 35 Subsidy occurs 0 to 10 depending on count-B-subsidy of Person(cnt-person). 40 Begin pic x(02). 40 End pic x(02). 40 Amount pic x(03). 30 Provdata. 35 Provision occurs 0 to 10 depending on count-B-provis of Person(cnt-person). 40 Begin pic x(02). 40 End pic x(02). 40 Amount pic x(03). 01 count-details. 05 cnt-person pic S9(04) binary. .... ....
2. 更新代码逻辑:操作当前Person实例的独立计数器
初始化每个Person实例时,将其内部计数器清零;填充子数据时,引用当前Person实例的计数器,而非全局计数器:
In a loop reading db2 table...person add 1 to cnt-person. move spaces to Person(cnt-person). move 0 to cnt-A-subsidy of Person(cnt-person) count-A-provis of Person(cnt-person) count-B-subsidy of Person(cnt-person) count-B-provis of Person(cnt-person). move table-idnr to Id of Person(cnt-person). move table-addr to Address of Person(cnt-person). then again reading another table in loop...fetch records and then, if subsidydataA. add 1 to cnt-A-subsidy of Person(cnt-person). move table-begin to Begin of subsidy of subsidydata of paymentA of Person(cnt-person) (cnt-A-subsidy of Person(cnt-person)). ... ... end. if ProvdataA. add 1 to count-A-provis of Person(cnt-person). move table-begin to Begin of Provision of provdata of paymentA of Person(cnt-person) (count-A-provis of Person(cnt-person)). ... ... end. if subsidydataB. add 1 to count-B-subsidy of Person(cnt-person). move table-begin to Begin of subsidy of subsidydata of paymentB of Person(cnt-person) (count-B-subsidy of Person(cnt-person)). ... ... end. if ProvdataB. add 1 to count-B-provis of Person(cnt-person). move table-begin to Begin of Provision of provdata of paymentB of Person(cnt-person) (count-B-provis of Person(cnt-person)). ... ... end. ..... then ended......
3. 生成无空标签XML的处理要点
生成XML时,针对每个Person实例做如下判断:
- 若
cnt-A-subsidy为0,不生成<subsidydata>标签; - 若
count-A-provis为0,不生成<provdata>标签; - 若
paymentA下的两个计数器均为0,不生成整个<paymentA>标签; - 同理处理
paymentB及其子标签,确保仅输出存在数据的节点。
内容的提问来源于stack exchange,提问作者MaMu
相关产品推荐
相关产品推荐

