Oracle PL/SQL UTL_HTTP.REQUEST-大括号/分号

Oracle PL/SQL UTL_HTTP.REQUEST-大括号/分号,oracle,plsql,Oracle,Plsql,我正在尝试使用Oracle Autonomy Database中的UTL_HTTP包调用URL,并获得一个ORA-06512: ORA-06502: PL/SQL: numeric or value error: character to number conversion error ORA-06512: at "SYS.UTL_HTTP", line 1810 ORA-06512: at "SYS.UTL_HTTP", line 144 ORA-065

我正在尝试使用Oracle Autonomy Database中的UTL_HTTP包调用URL,并获得一个ORA-06512:

ORA-06502: PL/SQL: numeric or value error: character to number conversion error
ORA-06512: at "SYS.UTL_HTTP", line 1810
ORA-06512: at "SYS.UTL_HTTP", line 144
ORA-06512: at "SYS.UTL_HTTP", line 1745
ORA-06512: at line 1
06502. 00000 -  "PL/SQL: numeric or value error%s"
*Cause:    An arithmetic, numeric, string, conversion, or constraint error
           occurred. For example, this error occurs if an attempt is made to
           assign the value NULL to a variable declared NOT NULL, or if an
           attempt is made to assign an integer larger than 99 to a variable
           declared NUMBER(2).
*Action:   Change the data, how it is manipulated, or how it is declared so
           that values do not violate constraints.
正确配置了所有网络ACL等

所讨论的URL需要直接在URL中使用JSON,我理解这是一种不好的做法,但是我无法控制API。如果删除大括号({})和分号(:),则使用UTL_HTTP的请求可以工作,但输出不正确,因为JSON变得无效

我尝试使用在线编码器以及UTL_URL.ESCAPE函数对URL进行编码,这会产生与上面相同的错误

UTL_URL.ESCAPE的编码为:

URL格式的一个示例是:

https://example.com/rest.php?entity=contact&action=get&json={"name": "Lorum Ipsum", "end_date": {"IS NULL": 1}, "return": "id,contact_id"}
我使用utl_http.request尝试了直接选择:

SELECT UTL_HTTP.REQUEST('https://example.com/rest.php?entity=contact&action=get&json={"name": "Lorum Ipsum", "end_date": {"IS NULL": 1}, "return": "id,contact_id"}') FROM DUAL;
并使用PL/SQL调用:

declare
    req UTL_HTTP.REQ;
    resp UTL_HTTP.RESP;
    val VARCHAR2(2000);
    str varchar2(1000);
begin
    req := UTL_HTTP.BEGIN_REQUEST('https://example.com/rest.php?entity=contact&action=get&json={"name": "Lorum Ipsum", "end_date": {"IS NULL": 1}, "return": "id,contact_id"}');
    resp := UTL_HTTP.GET_RESPONSE(req);
    LOOP
        UTL_HTTP.READ_LINE(resp, val, TRUE);
        DBMS_OUTPUT.PUT_LINE(val);
    END LOOP;
UTL_HTTP.END_RESPONSE(resp);
EXCEPTION
    WHEN UTL_HTTP.END_OF_BODY
THEN
    UTL_HTTP.END_RESPONSE(resp);
END;

/

如何使用UTL_HTTP调用此url?

他们在中讨论了这一点,但冒号是保留字符-它们在url的某些部分有效,但在其他部分无效。(大括号是不允许的。)关于它们在URL的查询部分是否有效的问题——RFC中的ABNF似乎说是的,但很多实现都不允许

默认情况下,
UTL\u URL.ESCAPE
不会转义保留字符(因为这会使
https://
部分出错,等等),但是您可以通过将TRUE作为第二个参数来更改它。通常,最佳做法似乎是转义可能包含保留字符的任何查询字符串中的保留字符:

req := UTL_HTTP.BEGIN_REQUEST('https://example.com/rest.php?entity=contact&action=get&json=' 
       || utl_url.escape('{"name": "Lorum Ipsum", "end_date": {"IS NULL": 1}, "return": "id,contact_id"}'
            ,TRUE));

查看是否有帮助?

请编辑问题并显示相关pl/sql代码。感谢您展示了SQL和PL/SQL的尝试。您是如何尝试编码URL的?使用
utl\u url.escape
或其他函数?您能显示输出吗?@kfinity我已编辑了原始问题,并提供了有关编码的更多信息。我无法提供实际URL的确切输出,因为它包含数据,但示例URL的URL具有相同的十六进制编码<代码>https://example.com/rest.php?entity=contact&action=get&json=%7B%22name%22:%20%22Lorum%20Ipsum%22,%20%22结束\u日期%22:%20%7B%22是%20NULL%22:%201%7D,%20%22返回%22:%20%22id,联系人\u id%22%7D我刚刚注意到冒号没有被UTL\u URL包编码,这可能是问题所在。这解决了问题。文档确实声明它不会逃逸冒号,正如您指出的,这是有充分理由的。使用类似于您所做的连接,或使用将冒号替换为%3A。您的解决方案更加优雅。谢谢