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

如何在Oracle PL/SQL中提取单个RESULT的JSON字符串?

PL/SQL提取CLOB中JSON数组的单个元素为JSON字符串

问题背景

我已在Oracle PL/SQL中实现JSON解析,但需从存储在CLOB列的API响应JSON里,提取每个RESULT对应的完整JSON字符串(每个RESULT等价于主表的一条记录)。不想使用INSTR、SUBSTR这类字符串操作方法,已知PowerShell中的实现方式,但客户仅允许使用PL/SQL。

API响应JSON结构

{"header1": "val_header1",
  "header2": "val_header2",
  "header3": "val_header3",
  "header4": "",
  "header5": "val_header5",
  "header6": ["val_header6"],
  "_embedded": {
    "results": [
      { "col1": "value1", "col2": "value2", "col3": "value3", "col4": "value4", "col5": "value5",
        "col6": [{"col6a": "", "col6b": "value6b"}],
        "col7a": {
          "col7a1": {"col7a1a": "value7a1a", "col7a1b": "value7a1b", "col7a1c": "value7a1c"},
          "col7b1": [
            {"col7b1a": "value7a1a-1", "col7b1b": "value7a1a-1", "col7b1c": "value7a1a-1"},
            {"col7b1a": "value7a1a-2", "col7b1b": "value7a1a-2", "col7b1c": "value7a1a-2"}
          ]
        },
        "_embedded": {}
      },
      { "col1": "value1", "col2": "value2", "col3": "value3", "col4": "value4", "col5": "value5",
        "col6": [{"col6a": "", "col6b": "value6b"}],
        "col7a": {
          "col7a1": {"col7a1a": "value7a1a", "col7a1b": "value7a1b", "col7a1c": "value7a1c"},
          "col7b1": [
            {"col7b1a": "value7a1a-1", "col7b1b": "value7a1a-1", "col7b1c": "value7a1a-1"},
            {"col7b1a": "value7a1a-2", "col7b1b": "value7a1a-2", "col7b1c": "value7a1a-2"}
          ]
        },
        "_embedded": {}
      },
      { "col1": "value1", "col2": "value2", "col3": "value3", "col4": "value4", "col5": "value5",
        "col6": [{"col6a": "", "col6b": "value6b"}],
        "col7a": {
          "col7a1": {"col7a1a": "value7a1a", "col7a1b": "value7a1b", "col7a1c": "value7a1c"},
          "col7b1": [
            {"col7b1a": "value7a1a-1", "col7b1b": "value7a1a-1", "col7b1c": "value7a1a-1"},
            {"col7b1a": "value7a1a-2", "col7b1b": "value7a1a-2", "col7b1c": "value7a1a-2"}
          ]
        },
        "_embedded": {}
      }
    ]
  }
}

PowerShell实现示例

# 请求API
$get_list = Invoke-WebRequest -Uri $get_url
# 转换为PowerShell对象
$json_object = $get_list | ConvertFrom-Json
# 遍历每个result
foreach ($json_obj_detail in $json_object._embedded.results)
{
    # 转换为压缩的JSON字符串
    $obj_det_json = $json_obj_detail | ConvertTo-Json -Depth 100 -Compress
}

期望得到的单个RESULT JSON字符串示例

{ "col1": "value1", "col2": "value2", "col3": "value3", "col4": "value4", "col5": "value5", "col6": [ { "col6a": "", "col6b": "value6b" } ], "col7a": { "col7a1": { "col7a1a": "value7a1a", "col7a1b": "value7a1b", "col7a1c": "value7a1c" }, "col7b1": [ { "col7b1a": "value7a1a-1", "col7b1b": "value7a1a-1", "col7b1c": "value7a1a-1" }, { "col7b1a": "value7a1a-2", "col7b1b": "value7a1a-2", "col7b1c": "value7a1a-2" } ], }, "_embedded": {} }

尝试过的SQL(未得到预期结果)

SELECT JSON_QUERY(jsn.clob_json,'$._embedded.results')
FROM json_documents jsn

PL/SQL解决方案

方法1:SQL查询直接提取

通过JSON_TABLE将results数组拆分为单行记录,再用JSON_QUERY提取每个元素的完整JSON,支持生成压缩格式:

SELECT 
  -- 提取格式化的JSON字符串
  JSON_QUERY(
    jsn.clob_json, 
    '$._embedded.results[' || jt.idx || ']' 
    RETURNING CLOB
    WITH WRAPPER FALSE
  ) AS result_json,
  -- 提取压缩后的JSON字符串(对应PowerShell的-Compress)
  JSON_SERIALIZE(
    JSON_QUERY(jsn.clob_json, '$._embedded.results[' || jt.idx || ']'),
    COMPACT
    RETURNING CLOB
  ) AS compressed_result_json
FROM json_documents jsn,
     JSON_TABLE(
       jsn.clob_json,
       '$._embedded.results[*]'
       COLUMNS idx FOR ORDINALITY
     ) jt;

方法2:PL/SQL块遍历处理

如果需要在PL/SQL逻辑中逐个处理每个RESULT,使用Oracle原生JSON对象API(Oracle 12cR2及以上支持):

DECLARE
  l_clob CLOB;
  l_root_obj JSON_OBJECT_T;
  l_results_arr JSON_ARRAY_T;
  l_result_obj JSON_OBJECT_T;
  l_result_json CLOB;
BEGIN
  -- 从表中获取目标CLOB格式JSON
  SELECT clob_json INTO l_clob FROM json_documents WHERE id = 1; -- 替换为实际筛选条件
  
  -- 解析根JSON对象
  l_root_obj := JSON_OBJECT_T(l_clob);
  -- 获取results数组
  l_results_arr := l_root_obj.get_Array('_embedded.results');
  
  -- 遍历数组中的每个RESULT元素
  FOR i IN 0 .. l_results_arr.get_size() - 1 LOOP
    l_result_obj := l_results_arr.get_Object(i);
    -- 转换为格式化JSON字符串
    l_result_json := l_result_obj.to_String();
    -- 如需压缩格式,替换为下面一行
    -- l_result_json := l_result_obj.to_String(JSON_OBJECT_T.COMPACT);
    
    -- 此处添加自定义处理逻辑,比如插入主表、输出等
    DBMS_OUTPUT.PUT_LINE(l_result_json);
  END LOOP;
EXCEPTION
  WHEN OTHERS THEN
    DBMS_OUTPUT.PUT_LINE('处理失败: ' || SQLERRM);
END;
/

说明

  • 两种方案均依赖Oracle原生JSON解析能力,避免了手动字符串操作,稳定性更高。
  • JSON_SERIALIZE(..., COMPACT)和to_String(JSON_OBJECT_T.COMPACT)均可生成压缩后的JSON,与PowerShell示例中的-Compress效果一致。
  • 需确保Oracle版本为12cR2及以上,原生JSON API才完全支持上述功能。

内容的提问来源于stack exchange,提问作者Johann Rosner

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 03:52:53