UTF-8 字符在 HTTP 响应 pl/sql 中损坏

Posted

技术标签:

【中文标题】UTF-8 字符在 HTTP 响应 pl/sql 中损坏【英文标题】:UTF-8 Characters get corrupted in HTTP response pl/sql 【发布时间】:2014-12-09 11:26:26 【问题描述】:

我正在使用以下代码从 Mongo DB 读取 HTTP 响应到 Oracle 表。某些部分的源(json-like)是中文的,收到损坏。 DBMS_OUTPUT.PUT_LINE(buf); 行显示这些损坏的值。

FUNCTION FN_READ_CONTACTS_MOB (p_id in number) RETURN NUMBER 是 OracleBatchNumber 编号:= p_id; buf NVARCHAR2(32767); l_param_list VARCHAR2(512); l_http_request UTL_HTTP.req; l_http_response UTL_HTTP.resp; l_response_text CLOB; 开始 DBMS_OUTPUT.ENABLE(1000000); -- 服务的输入参数 UTL_HTTP.SET_WALLET('file:C:/app/', 'manager1'); -- 准备请求... l_http_request := UTL_HTTP.begin_request('https://api.appery.io/rest/1/db/collections/Outlet_Details?where=%7B%22%24and%22%3A%5B%7B%22Oracle_Flag%22%3A+ %22Y%22%7D%2C+%7B%22OracleBatchNo%22%3A+%22'||OracleBatchNumber||'%22%7D%5D%7D' , '得到' , 'HTTP/1.1'); -- ...设置标题的属性 UTL_HTTP.set_header(l_http_request, 'X-Appery-Database-Id', '53f2dac5e4b02cca64021dbe'); --UTL_HTTP.set_header(l_http_request, '内容长度', LENGTH(l_param_list)); -- ...设置输入参数 -- UTL_HTTP.write_text(l_http_request, l_param_list); -- 获取响应并获取接收值 l_http_response := UTL_HTTP.get_response(l_http_request); -- 使用循环读取响应,因为 UTL_HTTP.read_text 帽子将结果作为 VARCHAR2(最大 32767)返回(这里有一个隐式转换)。 开始 环形 UTL_HTTP.read_text(l_http_response, buf); DBMS_OUTPUT.PUT_LINE(buf); l_response_text := l_response_text ||缓冲区; 结束循环; 例外 当 UTL_HTTP.end_of_body 那么 空值; 结尾; ......

当我运行以下命令时:

select value from nls_database_parameters where parameter='NLS_CHARACTERSET';

它返回:AL32UTF8。

不是说我的数据库是为 UTF-8 配置的吗?还是为此目的需要检查其他事项?

【问题讨论】:

我知道这是不久前的事了,但是您找到解决此问题的方法了吗?我有一些非常相似的东西:***.com/questions/68211873/… @Kabulan0lak,抱歉我不记得了。时间太长了 我找到了解决方案并将其发布为(非常)迟到的答案。它有效:) 【参考方案1】:

聚会有点晚了...解决方案是用dbms_lob“嵌套”数据,以便Oracle可以正确地将其转换回来:

DECLARE
    l_clob            CLOB;
    l_http_request    utl_http.req;
    l_http_response   utl_http.resp;
    l_text            VARCHAR2(32767);
BEGIN
    dbms_lob.createtemporary(l_clob, false);
    /* ... */

    BEGIN
        LOOP
            utl_http.read_text(l_http_response, l_text, 32766);
            dbms_lob.writeappend(l_clob, length(l_text), l_text);
        END LOOP;
    EXCEPTION
        WHEN utl_http.end_of_body THEN
            utl_http.end_response(l_http_response);
    END;

    /* l_clob contains your data now correctly encoded */

    dbms_lob.freetemporary(l_blob);
EXCEPTION
    WHEN OTHERS THEN
        utl_http.end_response(l_http_response);
        dbms_lob.freetemporary(l_blob);
        RAISE;
END;
/

希望这可以帮助其他人。从Donald Burleson's article 得到这个想法。

【讨论】:

【参考方案2】:

尝试将 persistant_conn_support 设置为 true,以便在超时之前收到完整的响应。

utl_http.set_persistent_conn_support(l_http_request,true);  -- keep connection open    

【讨论】:

以上是关于UTF-8 字符在 HTTP 响应 pl/sql 中损坏的主要内容,如果未能解决你的问题,请参考以下文章

PL/SQL:带有 UTF8 字符串的 UTL_HTTP POST 导致字符损坏

PL/SQL。使用 regexp_like 正则表达式解析 clob UTF8 字符

如何通过PL / SQL utl_http.html_pieces确定一个部分

如何使用 PL/SQL 循环遍历 json 响应?

为啥 SQL Developer 与 SQL Plus 中的 Oracle PL/SQL 响应时间存在差异?

在 PL/SQL 过程中解析具有名称空间的 XML 的未知数量节点?