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

如何在Oracle PLSQL中读取JSON中的动态嵌套对象?

在Oracle PL/SQL中读取动态嵌套JSON对象的方法

问题描述

需要读取如下JSON数据中discountDetail对象下的所有嵌套对象字段,但这些嵌套对象的ID是运行时生成的动态值,无法提前预知,如何在Oracle PL/SQL中实现?

示例JSON:

{
  "responseHeader": {
    "transactionId": "357910e9558654b6:20f4dee6:18d59ad95c2:-800056572",
    "status": {
      "code": "SUCCESS",
      "type": "S",
      "description": "TRANSACTION SUCCESSFUL"
    },
    "discountDetail": {
      "65300": {
        "discountId": "65300",
        "discountName": "Distributor Standard Discount - USD",
        "discountDescription": "Standard - Distributor Standard Discount - USD",
        "discountGroup": "Standard",
        "modifierLineTypeCode": "DIS",
        "discountMethodCode": "%",
        "modifierNumber": "Distributor Standard Discount - USD",
        "discountLineNumber": "Line, %",
        "listHeaderId": "0.0",
        "listLineId": "0.0",
        "priceBreakTypeCode": "N",
        "prorationTypeCode": "N",
        "postTermClause": false,
        "pricingPhaseId": "2",
        "accrualIndicator": "N",
        "automaticIndicator": "N",
        "updateIndicator": "Y",
        "appliedIndicator": "Y",
        "overRideableIndicator": "Y"
      },
      "230935": {
        "discountId": "230935",
        "discountName": "BR-Deal Registration-USD",
        "discountDescription": "Promotion-BR-Hunt-210731-10660",
        "discountGroup": "Promotion",
        "modifierLineTypeCode": "DIS",
        "discountMethodCode": "%",
        "modifierNumber": "BR-Deal Registration-USD",
        "discountLineNumber": "Line,%",
        "listHeaderId": "1566939",
        "listLineId": "254610462",
        "priceBreakTypeCode": "N",
        "discountType": "ES",
        "adjustmentMethodCode": "Additive",
        "pricingPhaseId": "2.0",
        "updateAllowableIndicator": "N",
        "updateIndicator": "Y",
        "appliedIndicator": "Y",
        "printOnInvoiceIndicator": "N"
      },
      "231832": {
        "discountId": "231832",
        "discountName": "BR-Special Offers-USD",
        "discountDescription": "Promotion-BR-MSSB-220730-12374",
        "discountGroup": "Promotion",
        "modifierLineTypeCode": "DIS",
        "discountMethodCode": "%",
        "modifierNumber": "BR-Special Offers-USD",
        "discountLineNumber": "Line,%",
        "listHeaderId": "561690",
        "listLineId": "94777454",
        "priceBreakTypeCode": "N",
        "prorationTypeCode": "N",
        "postTermClause": false,
        "pricingPhaseId": "2",
        "accrualIndicator": "N",
        "automaticIndicator": "N",
        "updateAllowableIndicator": "N",
        "updateIndicator": "Y",
        "appliedIndicator": "Y",
        "printOnInvoiceIndicator": "N",
        "overRideableIndicator": "N"
      }
    }
  }
}

解决方案

方法1:使用JSON_TABLE配合通配符直接解析

利用JSON_TABLE的通配符*匹配discountDetail下的所有动态键,直接解析对应对象的字段,无需提前知道ID值。

DECLARE
  l_json CLOB := '<上述完整JSON字符串>';
BEGIN
  FOR rec IN (
    SELECT 
      jt.discount_id,
      jt.discount_name,
      jt.discount_description,
      jt.discount_group,
      jt.modifier_line_type_code,
      jt.discount_method_code,
      jt.modifier_number,
      jt.discount_line_number,
      jt.list_header_id,
      jt.list_line_id,
      jt.price_break_type_code,
      jt.proration_type_code,
      jt.post_term_clause,
      jt.pricing_phase_id,
      jt.accrual_indicator,
      jt.automatic_indicator,
      jt.update_allowable_indicator,
      jt.update_indicator,
      jt.applied_indicator,
      jt.print_on_invoice_indicator,
      jt.over_rideable_indicator
    FROM 
      JSON_TABLE(
        l_json,
        '$.responseHeader.discountDetail.*'
        COLUMNS (
          discount_id VARCHAR2(50) PATH '$.discountId',
          discount_name VARCHAR2(200) PATH '$.discountName',
          discount_description VARCHAR2(500) PATH '$.discountDescription',
          discount_group VARCHAR2(50) PATH '$.discountGroup',
          modifier_line_type_code VARCHAR2(10) PATH '$.modifierLineTypeCode',
          discount_method_code VARCHAR2(10) PATH '$.discountMethodCode',
          modifier_number VARCHAR2(200) PATH '$.modifierNumber',
          discount_line_number VARCHAR2(50) PATH '$.discountLineNumber',
          list_header_id VARCHAR2(50) PATH '$.listHeaderId',
          list_line_id VARCHAR2(50) PATH '$.listLineId',
          price_break_type_code VARCHAR2(10) PATH '$.priceBreakTypeCode',
          proration_type_code VARCHAR2(10) PATH '$.prorationTypeCode',
          post_term_clause VARCHAR2(10) PATH '$.postTermClause',
          pricing_phase_id VARCHAR2(10) PATH '$.pricingPhaseId',
          accrual_indicator VARCHAR2(10) PATH '$.accrualIndicator',
          automatic_indicator VARCHAR2(10) PATH '$.automaticIndicator',
          update_allowable_indicator VARCHAR2(10) PATH '$.updateAllowableIndicator',
          update_indicator VARCHAR2(10) PATH '$.updateIndicator',
          applied_indicator VARCHAR2(10) PATH '$.appliedIndicator',
          print_on_invoice_indicator VARCHAR2(10) PATH '$.printOnInvoiceIndicator',
          over_rideable_indicator VARCHAR2(10) PATH '$.overRideableIndicator'
        )
      ) jt
  ) LOOP
    -- 处理每条折扣记录,示例为打印关键信息
    DBMS_OUTPUT.PUT_LINE('折扣ID: ' || rec.discount_id || ',折扣名称: ' || rec.discount_name);
  END LOOP;
END;
/

方法2:使用JSON_OBJECT_T动态遍历键值

如果字段也存在动态变化的可能,可使用Oracle 12c+引入的JSON_OBJECT_T类型,通过get_keys()获取所有动态ID,再逐个解析对应对象的字段。

DECLARE
  l_json_obj JSON_OBJECT_T;
  l_discount_detail JSON_OBJECT_T;
  l_keys JSON_KEY_LIST;
  l_discount_obj JSON_OBJECT_T;
  i NUMBER := 1;
BEGIN
  l_json_obj := JSON_OBJECT_T('<上述完整JSON字符串>');
  
  -- 获取discountDetail对象
  l_discount_detail := l_json_obj.get_object('responseHeader').get_object('discountDetail');
  -- 获取所有动态ID
  l_keys := l_discount_detail.get_keys();
  
  -- 遍历每个ID对应的折扣对象
  WHILE i <= l_keys.COUNT LOOP
    l_discount_obj := l_discount_detail.get_object(l_keys(i));
    
    -- 读取并打印字段
    DBMS_OUTPUT.PUT_LINE('动态ID: ' || l_keys(i));
    DBMS_OUTPUT.PUT_LINE('折扣ID: ' || l_discount_obj.get_string('discountId'));
    DBMS_OUTPUT.PUT_LINE('折扣名称: ' || l_discount_obj.get_string('discountName'));
    -- 其他字段可按需读取,若字段也动态,可继续用get_keys遍历字段
    
    i := i + 1;
  END LOOP;
END;
/

内容的提问来源于stack exchange,提问作者Sadashiv Gawade

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 23:05:00