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

如何用Oracle APEX的make_rest_request逐行传递JSON调用REST API?

优化Oracle APEX调用REST API的JSON处理方案

你的逐行调用方案可以正常工作,但可以从性能、代码简洁性两方面优化;如果目标API支持批量接收JSON数组,那一次性提交是最优方案,以下是具体实现:

一、优化逐行调用的实现

1. 减少冗余操作

请求头(Content-Type、Authorization等)是固定配置,无需每次循环重复设置,移到循环外执行:

-- 循环外一次性设置请求头
begin
    apex_web_service.set_request_headers(
        p_name_01        => 'Content-Type',
        p_value_01       => 'application/json',
        p_name_02        => 'User-Agent',
        p_value_02       => 'APEX',
        p_name_03        => 'Authorization',
        p_value_03       => 'Basic xxxasdasdasdsaddsadsdsasfsafa',
        p_reset          => true,
        p_skip_if_exists => true );
end;

-- 定义与游标匹配的记录类型,简化字段赋值
type t_api_record is record(
    field1  varchar2(200),
    field2  number,
    field3  date,
    -- ... 补充剩余12个字段
    field15 varchar2(100)
);
l_rec t_api_record;

loop 
    fetch l_cursor into l_rec;
    exit when l_cursor%notfound;
    
    -- 初始化JSON输出,避免残留数据
    apex_json.initialize_clob_output(p_indent => 0); -- 关闭缩进减少JSON体积
    apex_json.open_object;
    apex_json.write(l_rec); -- 直接写入整个记录,自动匹配字段名
    apex_json.close_object;
    
    lclob_body := apex_json.get_clob_output;
    apex_json.free_output;

    begin
        v_response := apex_web_service.make_rest_request(
                            p_url           => 'https://....api_url',
                            p_http_method   => 'POST',
                            p_body          => lclob_body
                        );
        dbms_output.put_line('Success: ' || v_response);
    exception 
        when others then 
            -- 不要吞掉异常,记录错误便于排查
            dbms_output.put_line('Error: ' || sqlerrm || ' | Record: ' || lclob_body);
    end;
end loop;
close l_cursor; -- 务必关闭游标释放资源

2. 额外性能优化点

  • 处理大量数据时,用APEX_JOB或DBMS_SCHEDULER异步执行,避免阻塞主会话;
  • 若需频繁调用,可考虑缓存请求头(通过p_reset => false),但注意权限和配置变更场景。

二、最优方案:批量提交(API支持时)

如果目标REST API接受JSON数组格式(如[{"field1":"val1"},{"field1":"val2"}]),直接生成数组一次性提交,将N次HTTP请求压缩为1次,性能提升显著:

type t_api_record is record(
    field1  varchar2(200),
    field2  number,
    -- ... 补充剩余字段
    field15 varchar2(100)
);
l_rec t_api_record;

-- 生成JSON数组
apex_json.initialize_clob_output(p_indent => 0);
apex_json.open_array;

loop
    fetch l_cursor into l_rec;
    exit when l_cursor%notfound;
    
    apex_json.open_object;
    apex_json.write(l_rec);
    apex_json.close_object;
end loop;
close l_cursor;

apex_json.close_array;
lclob_body := apex_json.get_clob_output;
apex_json.free_output;

-- 单次调用API提交批量数据
begin
    apex_web_service.set_request_headers(
        p_name_01        => 'Content-Type',
        p_value_01       => 'application/json',
        p_name_02        => 'User-Agent',
        p_value_02       => 'APEX',
        p_name_03        => 'Authorization',
        p_value_03       => 'Basic xxxasdasdasdsaddsadsdsasfsafa',
        p_reset          => true,
        p_skip_if_exists => true );
        
    v_response := apex_web_service.make_rest_request(
                        p_url           => 'https://....api_url',
                        p_http_method   => 'POST',
                        p_body          => lclob_body
                    );
    dbms_output.put_line('Batch Response: ' || v_response);
exception
    when others then
        dbms_output.put_line('Batch Error: ' || sqlerrm);
end;

三、原方案问题解析

你最初用apex_json.write(l_sys_refcursor)时,apex_json默认将游标解析为单条记录,因此仅生成第一行的JSON对象,导致API只收到第一条数据。若要生成多行结构,必须手动循环包裹在JSON数组中,即批量方案的写法。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 05:45:48