Oracle 12.2使用UTL_HTTP发POST请求报ORA-06502字符转数字错误
错误触发原因
报错指向第11行req := utl_http.begin_request(url, 'POST',' HTTP/1.1', host);,核心问题是UTL_HTTP.BEGIN_REQUEST的参数传参错误:
- 该过程的第四个入参为
request_context,类型是RAW,作用是传入请求上下文标识,不接收Host头值。代码中将VARCHAR2类型的host变量传入该参数位,Oracle会隐式尝试将字符串转换为RAW类型,直接触发字符到类型转换的ORA-06502错误。 - 第三个参数
http_version传入值为' HTTP/1.1',前面多了一个多余的前导空格,属于非法HTTP版本字符串,即使参数位置正确也会导致后续请求异常。 - Host属于普通HTTP请求头,不需要作为
begin_request的入参传递,需要和其他请求头一样通过set_header过程设置。
修复方案
- 修正
begin_request调用:移除错误传入的第四个host参数,删除HTTP版本字符串前的多余空格 - 新增单独的Host请求头设置逻辑
- 将Content-Length的长度计算从
length(content)改为lengthb(content):HTTP协议要求Content-Length为请求体的字节长度,length按字符计数,遇到多字节字符时会出现长度计算错误导致请求体截断。
修正后的完整代码如下:
declare req utl_http.req; res utl_http.resp; url varchar2(4000) := 'http://localhost:9002/cinema'; host varchar2(4000) := 'test.com'; name varchar2(4000); buffer varchar2(4000); -- 若接口要求room、partySize为数值类型,可去掉值两侧的双引号 content varchar2(4000) := '{"room":"'||p_room_id||'", "partySize":"'||p_party_Size||'"}'; begin req := utl_http.begin_request(url, 'POST','HTTP/1.1'); utl_http.set_header(req, 'user-agent', 'mozilla/4.0'); utl_http.set_header(req, 'content-type', 'application/json'); utl_http.set_header(req, 'Host', host); utl_http.set_header(req, 'Content-Length', lengthb(content)); utl_http.write_text(req, content); res := utl_http.get_response(req); begin loop utl_http.read_line(res, buffer); 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; /
额外注意事项
- 若接口要求
room、partySize为数值类型,拼接JSON时去掉值两侧的双引号即可,避免参数类型不匹配。 - Oracle 12c默认开启网络访问控制(ACL),若修复后出现ORA-24247错误,需要给执行该PL/SQL的用户授予目标地址
localhost:9002的网络访问权限。
内容的提问来源于stack exchange,提问作者Ramiz Tariq
相关产品推荐
相关产品推荐

