我遇到了
PL/SQL
函数的问题,该函数使用 HTTP(S)
发出 UTL_HTTP
请求。该函数应该向特定 URL 发送 POST 请求。它几乎按预期工作,但有一个特殊的问题。
这是我正在使用的功能:
create or replace function send_post_request (p_url in varchar2,
p_content in clob default null)
return clob
is
v_url varchar2 (255);
req utl_http.req;
resp utl_http.resp;
buffer varchar2 (32767);
response clob;
begin
v_url := p_url;
utl_http.set_wallet (
'file:/wallet_path',
'password');
utl_http.set_transfer_timeout (300);
req :=
utl_http.begin_request (v_url, 'post', utl_http.http_version_1_1);
utl_http.set_authentication (req, '<hidden>', '<hidden>');
utl_http.set_header (req, 'user-agent', 'mozilla/4.0');
utl_http.set_header (req, 'content-type', 'application/json');
if p_content is not null
then
utl_http.set_body_charset ('utf-8');
utl_http.set_header (req,
'content-length',
lengthb (to_char (p_content)));
utl_http.write_text (req, p_content);
end if;
resp := utl_http.get_response (req);
utl_http.set_body_charset (r => resp, charset => 'utf-8');
if resp.status_code != utl_http.http_ok
then
raise_application_error (
-20001,
'response status code: ' || resp.status_code);
end if;
begin
loop
utl_http.read_text (resp, buffer);
response := response || buffer;
end loop;
utl_http.end_request (req);
utl_http.end_response (resp);
return response;
exception
when utl_http.end_of_body
then
utl_http.end_request (req);
utl_http.end_response (resp);
return response;
end;
exception
when others
then
utl_http.end_request (req);
utl_http.end_response (resp);
raise_application_error (
-20002,
sqlerrm || ' / ' || utl_http.get_detailed_sqlerrm);
end;
我遇到的问题是,第一次调用这个函数时,它会抛出异常,并显示以下错误消息:
ORA-29273: HTTP request failed / ORA-29259: end-of-input reached.
奇怪的是,当我在遇到错误后立即第二次调用该函数时,它执行时没有任何问题并给出了预期的结果。
我已经检查了 Oracle Wallet 设置、HTTPS 端点和请求有效负载,它们似乎配置正确,特别是考虑到该函数在第二次和后续执行时有效。
是否有其他人遇到过这种情况,或者对为什么第一次执行可能失败而后续执行运行没有任何问题有任何想法?任何见解将不胜感激。
注意:出于安全目的隐藏了 set_authentication 参数
到目前为止,我已尝试以下步骤来调试并解决此问题:
UTL_HTTP.SET_WALLET
的钱包文件路径和密码,以确保它们正确。UTL_HTTP.BEGIN_REQUEST
中指定的 HTTP 版本是否适合我正在与之通信的服务器。'Content-Type'
。它们似乎针对我的用例进行了正确设置。
尽管做出了这些尝试,问题仍然存在。特殊的问题是,错误仅发生在函数的第一次执行时,而不会发生在后续执行时,我正在努力解释这一点。我正在寻找有关为什么会发生这种情况的见解,以及如何确保该函数即使在第一次执行时也能正常工作。
尝试设置 HTTP 标头
Transfer-Encoding: chunked
并删除标头“content-length”。它适用于 HTTP 版本 1.1。