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

使用PL/SQL调用REST API时请求体未被识别的问题排查

问题描述

我是论坛新手,正在学习使用PL/SQL调用REST API。尝试调用RapidAPI提供的免费weatherapi-com接口,但服务器无法识别请求参数。相同请求在Postman中可正常执行,推测问题出在PL/SQL代码中。

存储过程代码

Create Or Replace Procedure TEST_REST_API
(
  PURL IN VARCHAR2
)

is
  req utl_http.req;
  res utl_http.resp;
  url varchar2(4000) := PURL;
  buffer varchar2(32767);
  content varchar2(8000);
begin
  dbms_output.put_line('START'); 
  UTL_TCP.close_all_connections;
  DBMS_OUTPUT.put_line('2');
  UTL_HTTP.set_wallet('file:/u01/app/oracle/product/11.2.0/db_1/wallet/rapidapi','wallet123');
  DBMS_OUTPUT.put_line('3');
  UTL_HTTP.CLEAR_COOKIES();
  content := '{"q":"autp:ip"}';
  --content := '';
  dbms_output.put_line('content '||content);
  req := utl_http.begin_request(url, 'GET',' HTTP/1.1');
  utl_http.set_header(req, 'X-RapidAPI-Key', 'af1e7931bamsh3ac102afa8fef68p100423jsn8d4d3cc1325b');
  utl_http.set_header(req, 'X-RapidAPI-Host', 'weatherapi-com.p.rapidapi.com');
  utl_http.set_header(req, 'Content-Length', length(content));
  utl_http.set_header(req, 'User-Agent', 'mozilla/4.0'); 
  --utl_http.set_header(req, 'user-agent', 'PostmanRuntime/7.29.2'); 
  utl_http.set_header(req, 'Content-Type', 'application/json');
  utl_http.set_header(req, 'Connection','keep-alive');
  --utl_http.set_header(req, 'Accept','*/*');
  --utl_http.write_text(req, content);
  utl_http.write_text(req, content);
  --utl_http.write_text(req,'');
  --insert into wstemp values (req);
  res := utl_http.get_response(req);
  -- process the response from the HTTP call
  begin
    loop
      utl_http.read_line(res, buffer,TRUE);
      dbms_output.put_line(buffer);
    end loop;
    dbms_output.put_line('Response XML:'|| cast(x_clob as varchar2));
    utl_http.end_response(res);
  exception
    when utl_http.end_of_body 
    then
      utl_http.end_response(res);
  end;
end;

执行脚本

BEGIN
TEST_REST_API
(
  'https://weatherapi-com.p.rapidapi.com/ip.json'
);
END;
/

服务器返回响应

{"error":{"code":1003,"message":"Parameter q is missing."}}

解决方法

问题根源有两个:

  • GET请求不支持通过请求体传参:你当前用GET请求却尝试通过utl_http.write_text写入JSON请求体,但绝大多数REST API的GET接口只会读取URL查询字符串中的参数,不会解析请求体。Postman能正常执行,大概率是你在Postman里把q参数放在了URL查询参数中,而非请求体。
  • JSON格式与拼写错误:你写的'{"q":"autp:ip"}'是HTML转义后的格式,PL/SQL中应直接写'{"q":"auto:ip"}',且你还把auto误写为autp。

针对该接口,正确做法是将q参数拼接到URL的查询字符串中,修改后的代码如下:

修改后的存储过程

Create Or Replace Procedure TEST_REST_API
(
  PURL IN VARCHAR2,
  P_Q_PARAM IN VARCHAR2 DEFAULT 'auto:ip'
)

is
  req utl_http.req;
  res utl_http.resp;
  url_with_param varchar2(4000);
  buffer varchar2(32767);
begin
  dbms_output.put_line('START'); 
  UTL_TCP.close_all_connections;
  DBMS_OUTPUT.put_line('2');
  UTL_HTTP.set_wallet('file:/u01/app/oracle/product/11.2.0/db_1/wallet/rapidapi','wallet123');
  DBMS_OUTPUT.put_line('3');
  UTL_HTTP.CLEAR_COOKIES();
  
  -- 拼接查询参数到URL,用utl_url.escape处理特殊字符
  url_with_param := PURL || '?q=' || utl_url.escape(P_Q_PARAM);
  dbms_output.put_line('Final URL: ' || url_with_param);
  
  req := utl_http.begin_request(url_with_param, 'GET','HTTP/1.1');
  utl_http.set_header(req, 'X-RapidAPI-Key', 'af1e7931bamsh3ac102afa8fef68p100423jsn8d4d3cc1325b');
  utl_http.set_header(req, 'X-RapidAPI-Host', 'weatherapi-com.p.rapidapi.com');
  utl_http.set_header(req, 'User-Agent', 'mozilla/4.0'); 
  utl_http.set_header(req, 'Connection','keep-alive');
  
  res := utl_http.get_response(req);
  
  -- 处理响应
  begin
    loop
      utl_http.read_line(res, buffer,TRUE);
      dbms_output.put_line(buffer);
    end loop;
    utl_http.end_response(res);
  exception
    when utl_http.end_of_body 
    then
      utl_http.end_response(res);
  end;
end;

修改后的执行脚本

BEGIN
TEST_REST_API
(
  'https://weatherapi-com.p.rapidapi.com/ip.json'
);
END;
/

额外注意事项:

  • 调用GET接口严格遵循REST规范,用查询字符串传递参数,避免请求体传参。
  • 用utl_url.escape处理参数值,防止特殊字符破坏URL格式。
  • 仔细检查参数拼写,避免低级错误。

内容的提问来源于stack exchange,提问作者Faheem Ahmed Shaik

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 05:10:31