如何在嵌套数组中使用 apex_json.get_count

Posted

技术标签:

【中文标题】如何在嵌套数组中使用 apex_json.get_count【英文标题】:How to use apex_json.get_count in a nested array 【发布时间】:2021-04-15 18:09:32 【问题描述】:

我正在尝试从我的 json 中的好处元素的计数中循环遍历数组。尽管 apex json 中的 get count 函数返回一个数字,但我不断收到数值错误。

如果我们将循环更改为 for 1 in 1..2 - 它可以正常工作。

如果我们将数组索引硬编码为 1,则代码有效,但如果我们尝试使用 %d p0 传递变量,则会出现数值错误 - ORA - 06502。

下面是代码:

  j              apex_json.t_values; 
  l_count_chg    number;
  l_count_pers   number;
  l_count_ben    number;
  
  l_members      wwv_flow_t_varchar2;
  l_paths        apex_t_varchar2;
  l_paths2       apex_t_varchar2;
  l_paths3       apex_t_varchar2; 

  v_get_person   varchar2(10); 
  v_get_benefit  varchar2(10);
  v_get_benopt   varchar2(10);
  r_count        number;
  
begin

  apex_json.parse(j,'
    "PolicyUpdate": 
        "contractNumber": 12345,
        "effectiveDate": "2022-04-01",
        "planChanges": [
            
                "changeCode": 1,
                "roleplayerId": "pers1",
                "person": 
                    "id": "pers1",
                    "surname": "Hazy",
                    "firstName": "Smith",
                    "benefits": [
                        
                            "Id": "ben1",
                            "typeCode": "C1",
                            "benefitName": "Funeral Benefit",
                            "roleplayerId": "pers1",
                            "coverAmount": 10000,
                            "premiumAmount": 47.47,
                            "StartDate": "2021-04-01",
                            "Options": 
                                "Option": [
                                    
                                        "Label": "Risk Benefit Classification",
                                        "Value": "Main Life"
                                    ,
                                    
                                        "Label": "Waiting Period (DOC to Event)",
                                        "Value": "6 Months"
                                    ,
                                    
                                        "Label": "Paid Up Benefit (Y/N)",
                                        "Value": "No"
                                    
                                ]
                            
                        ,
                        
                            "Id": "ben2",
                            "typeCode": "C1",
                            "benefitName": "Tombstone Benefit",
                            "roleplayerId": "pers1",
                            "coverAmount": 5000,
                            "premiumAmount": 10.47,
                            "StartDate": "2021-04-01"
                        
                    ]
                
            ,
            
                "changeCode": 2,
                "roleplayerId": "pers2"
            
        ]
    
');

  dbms_output.put_line('Contract Number  : ' ||
                       apex_json.get_varchar2(p_path => 'PolicyUpdate.contractNumber'));
  dbms_output.put_line('Effective Adte   : ' ||
                       apex_json.get_varchar2(p_path => 'PolicyUpdate.effectiveDate'));
  dbms_output.put_line('----------------------------------------');
  
  
  l_count_chg := apex_json.get_count(p_path => 'PolicyUpdate.planChanges',p_values=>j);
  dbms_output.put_line('change count '||l_count_chg);
  
  for i in 1..l_count_chg loop   
    dbms_output.put_line('changeCode    '||apex_json.get_varchar2(p_path => 'PolicyUpdate.planChanges[%d].changeCode'  ,p_values=>j,p0     => i));
    dbms_output.put_line('roleplayerId  '||apex_json.get_varchar2(p_path => 'PolicyUpdate.planChanges[%d].roleplayerId',p_values=>j,p0     => i));   
    dbms_output.put_line('firstname     '||apex_json.get_varchar2(p_path => 'PolicyUpdate.planChanges[%d].person.firstName',p_values=>j,p0 => i));                                   
    
    l_count_ben := apex_json.get_count(p_path => 'PolicyUpdate.planChanges[%d].person.benefits',p_values=>j);   
    dbms_output.put_line('benefit count '|| l_count_ben);
    
    for x in 1..l_count_ben loop    
      dbms_output.put_line('ben id        '||apex_json.get_varchar2(p_path => 'PolicyUpdate.planChanges[%d].person.benefits[%d].Id',p_values=>j,p0 => i,p1 => x));       
    end loop;    
                     
  end loop; 
  
end;

【问题讨论】:

【参考方案1】:

对我来说,计数没有返回数字(只是没有值),所以我做了一些更改 - 我发现在获取计数之前检查路径是否存在是最安全的:

declare
  j              apex_json.t_values; 
  l_count_chg    number;
  l_count_pers   number;
  l_count_ben    number;
  
  l_members      wwv_flow_t_varchar2;
  l_paths        apex_t_varchar2;
  l_paths2       apex_t_varchar2;
  l_paths3       apex_t_varchar2; 

  v_get_person   varchar2(10); 
  v_get_benefit  varchar2(10);
  v_get_benopt   varchar2(10);
  r_count        number;
  
begin

  apex_json.parse(j,'
    "PolicyUpdate": 
        "contractNumber": 12345,
        "effectiveDate": "2022-04-01",
        "planChanges": [
            
                "changeCode": 1,
                "roleplayerId": "pers1",
                "person": 
                    "id": "pers1",
                    "surname": "Hazy",
                    "firstName": "Smith",
                    "benefits": [
                        
                            "Id": "ben1",
                            "typeCode": "C1",
                            "benefitName": "Funeral Benefit",
                            "roleplayerId": "pers1",
                            "coverAmount": 10000,
                            "premiumAmount": 47.47,
                            "StartDate": "2021-04-01",
                            "Options": 
                                "Option": [
                                    
                                        "Label": "Risk Benefit Classification",
                                        "Value": "Main Life"
                                    ,
                                    
                                        "Label": "Waiting Period (DOC to Event)",
                                        "Value": "6 Months"
                                    ,
                                    
                                        "Label": "Paid Up Benefit (Y/N)",
                                        "Value": "No"
                                    
                                ]
                            
                        ,
                        
                            "Id": "ben2",
                            "typeCode": "C1",
                            "benefitName": "Tombstone Benefit",
                            "roleplayerId": "pers1",
                            "coverAmount": 5000,
                            "premiumAmount": 10.47,
                            "StartDate": "2021-04-01"
                        
                    ]
                
            ,
            
                "changeCode": 2,
                "roleplayerId": "pers2"
            
        ]
    
');

  dbms_output.put_line('Contract Number  : ' ||
                       apex_json.get_varchar2(p_path => 'PolicyUpdate.contractNumber',p_values => j));
  dbms_output.put_line('Effective Adte   : ' ||
                       apex_json.get_varchar2(p_path => 'PolicyUpdate.effectiveDate',p_values => j));
  dbms_output.put_line('----------------------------------------');
  
  
  l_count_chg := apex_json.get_count(p_path => 'PolicyUpdate.planChanges',p_values=>j);
  dbms_output.put_line('change count '||l_count_chg);
  
  for i in 1..l_count_chg loop   
    dbms_output.put_line('changeCode    '||apex_json.get_varchar2(p_path => 'PolicyUpdate.planChanges[%d].changeCode'  ,p_values=>j,p0     => i));
    dbms_output.put_line('roleplayerId  '||apex_json.get_varchar2(p_path => 'PolicyUpdate.planChanges[%d].roleplayerId',p_values=>j,p0     => i));   
    dbms_output.put_line('firstname     '||apex_json.get_varchar2(p_path => 'PolicyUpdate.planChanges[%d].person.firstName',p_values=>j,p0 => i));                                   


    IF apex_json.does_exist(p_path => 'PolicyUpdate.planChanges[%d].person.benefits',p0 => i,p_values=>j) THEN 
      l_count_ben := apex_json.get_count(p_path => 'PolicyUpdate.planChanges[%d].person.benefits',p0 => i,p_values=>j);   
      dbms_output.put_line('benefit count '|| l_count_ben);
      for x in 1..l_count_ben loop    
        dbms_output.put_line('ben id        '||apex_json.get_varchar2(p_path => 'PolicyUpdate.planChanges[%d].person.benefits[%d].Id',p_values=>j,p0 => i,p1 => x));       
      end loop;    
    END IF;                      
  end loop; 
end;

【讨论】:

【参考方案2】:

Koen 建议使用 EXISTS 进行测试非常好。

他也添加了这个,但没有说明您的原始版本似乎缺少参数:

p0 => i

在计算l_count_ben

所以 get_count 的值是未知的。

【讨论】:

以上是关于如何在嵌套数组中使用 apex_json.get_count的主要内容,如果未能解决你的问题,请参考以下文章

如何使用json方法解析android中没有键名的数组内的嵌套json编码数组?

嵌套数组内的Mongodb增量值

如何在猫鼬中更新嵌套数组值

如何在 mongodb 聚合中展开嵌套对象数组?

如何从 1 分钟的嵌套数组数据中聚合 OHLC 5 分钟(mongodb、mongoose)

如何更新猫鼬嵌套数组文档[重复]