• 记一次使用utl_http方法调用接口,报字符或值错误


    背景:ebs系统和其他系统通过utl_http包调用接口,使用log方法记录日志。

    某次调用接口,执行到记录日志行报字符或值错误。

    查找原因,发现是p_str的长度超过的32767的限制。

    解决办法:

     PROCEDURE log(p_str VARCHAR2) IS
      BEGIN
        fnd_file.put_line(fnd_file.log, p_str);
        dbms_output.put_line(p_str);
      END;
    --解决l_messge_clob长度超过32767导致的溢出问题,字符或值错误
    FOR i IN 0 .. trunc((dbms_lob.getlength(l_messge_clob) - 1) / l_step) LOOP
      log(dbms_lob.substr(l_messge_clob, l_step, i * l_step + 1));
    END LOOP;
    
    
    --同样 utl_http.write_text 长度不能超过32767,
    
    buffer       VARCHAR2(2000);
    offset       NUMBER := 1;
    amount       NUMBER := 1024;
    
    
    --解决l_messge_clob长度超过3276导致的溢出问题,字符或值错误
    ---utl_http.write_text(l_req, p_content);
    UTL_HTTP.SET_BODY_CHARSET('UTF-8');
    WHILE (offset < v_req_length) LOOP
      dbms_lob.read(p_content, amount, offset, buffer);
      utl_http.write_text(r => l_req, data => buffer);
      offset := offset + amount;
    END LOOP;

    DECLARE
      v_doc_fin    CLOB := '';
      req          utl_http.req;
      res          utl_http.resp;
      url          VARCHAR2(1900) := 'url xxx';
      v_value      VARCHAR2(4000);
      vchunkdata   VARCHAR2(2000);
      v_req_length NUMBER;
      buffer       VARCHAR2(32767);
      offset       NUMBER := 1;
      amount       NUMBER := 32767;
      utl_err      VARCHAR2(1000);
    BEGIN
      IF v_doc_fin IS NOT NULL THEN
        --v_doc_fin is JSON DOC of CLOB data type from a procedure
        v_req_length := dbms_lob.getlength(v_doc_fin);
        dbms_output.put_line(v_req_length);
        req := utl_http.begin_request(url, 'POST', 'HTTP/1.1');
        utl_http.set_header(req, 'Content-Length', v_req_length);
        utl_http.set_header(req, 'user-agent', 'mozilla/4.0');
        utl_http.set_header(req,
                            'content-type',
                            'application/json;charset=UTF-8');
        utl_http.set_header(req, 'Transfer-Encoding', 'chunked');
        utl_http.set_body_charset('UTF-8');
        WHILE (offset < v_req_length) LOOP
          dbms_lob.read(v_doc_fin, amount, offset, buffer);
          utl_http.write_text(r => req, data => buffer);
          offset := offset + amount;
        END LOOP;
        res := utl_http.get_response(req);
        BEGIN
          LOOP
            utl_http.read_line(res, v_value);
            dbms_output.put_line(v_value);
          END LOOP;
          utl_http.end_response(res);
        EXCEPTION
          WHEN utl_http.end_of_body THEN
            utl_http.end_response(res);
          WHEN utl_http.too_many_requests THEN
            utl_http.end_response(res);
          WHEN OTHERS THEN
            dbms_output.put_line(utl_http.get_detailed_sqlerrm);
            dbms_output.put_line(dbms_utility.format_error_stack);
            dbms_output.put_line(dbms_utility.format_error_backtrace);
            dbms_output.put_line(dbms_utility.format_call_stack);
        END;
      END IF;
    EXCEPTION
      WHEN OTHERS THEN
        utl_http.end_response(res);
        utl_err := utl_http.get_detailed_sqlerrm;
    END;

    参考:

    Oracle 通过UTL_HTTP 发送http请求并处理发送内容中包含空格和特殊字符的问题

    utl_http request and response stops when  > 32k

    UTTL_HTTP to POST CLOB request

    http://www.orafaq.com/forum/t/202946/

  • 相关阅读:
    用于 webpack 打包后方便修改的配置文件
    antd 中对树形表格中二级元素进行筛选过滤
    layui快速搭建一个后台管理系统
    centos使用shell定时清空缓存
    内存异常原因查询
    Protocol "‘https" not supported or disabled in libcurl
    HTML table标签实现表头固定
    vue 查询某个对象在对象列表的索引位置
    vue 实现页面监听键盘按键 上下左右
    Vue 实现图片监听鼠标滑轮滚动实现图片缩小放大功能
  • 原文地址:https://www.cnblogs.com/huanghongbo/p/7145365.html
Copyright © 2020-2023  润新知