You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 19:45:57