【问题标题】:How to set UTF8 encoding in Oracle?如何在 Oracle 中设置 UTF8 编码?
【发布时间】:2020-07-28 11:55:06
【问题描述】:

我有以下使用 utl_http 发送一些数据的过程

    procedure DoSomeThing is
      HttpRequest      utl_http.req;
      HttpResponse     utl_http.resp;      
      ResponseText     clob; 
      URL              varchar2(500) := 'https://someurl';
      PostPrameters    varchar2(30000);
    begin
      PostPrameters := 'Très cool';    
      PostPrameters := utl_url.escape(PostPrameters);      
      URL := utl_url.escape(URL,false,'UTF-8');
      
      UTL_HTTP.SET_BODY_CHARSET('UTF-8');
      HttpRequest := utl_http.begin_request(URL, 'POST', 'HTTP/1.1');    
      utl_http.set_authentication(HttpRequest, UserName, Password);      

      utl_http.set_header(HttpRequest,'Content-Type','application/x-www-form-urlencoded;');
      utl_http.set_header(HttpRequest, 'Content-Length',length(PostPrameters));
      utl_http.write_text(HttpRequest, PostPrameters);    
      HttpResponse := utl_http.get_response(HttpRequest);    
      utl_http.read_text(HttpResponse,ResponseText);   
      utl_http.end_response(HttpResponse);            
    end; 

我要发送的数据包含一些特殊字符:'Très cool'

从 SQL Developer 测试此过程时,特殊字符会正确发送到服务器。

    exec DoSomeThing;  << Works great from SQL Developer

但是,该过程应该从以下工作启动:

    Jobname := dbms_scheduler.generate_job_name('Job_');            
    JobAction := 'begin DoSomeThing; end;';                                                               
    dbms_scheduler.create_job(job_name => Jobname, job_type => 'PLSQL_BLOCK', job_action => JobAction, enabled => true);  

在这种情况下,完全相同的程序不会发送特殊字符。它会跳过它们:'Tr?s cool'

我想这是因为我在 SQL Developer 上的会话与工作中的会话没有相同的特征。

请问有人知道怎么解决吗?

干杯,

【问题讨论】:

  • 你的数据库的字符集是什么??
  • 请问如何获得?
  • SQL&gt; select value from nls_database_parameters where parameter = 'NLS_CHARACTERSET' ;
  • 从 SQL Developer 中返回:AL32UTF8
  • 我不知道所有会话是否都一样

标签: oracle


【解决方案1】:

这是解决方案。

由于某种原因我无法弄清楚,如果从 SQL 开发人员运行或从计划作业运行,以下方法不会返回相同的结果。 (当然不是针对 SQL 开发人员,而是针对某些会话参数)

utl_url.escape(PostPrameters)

来自我的 SQL 开发者会话

utl_url.escape('Très cool') 返回 'Tr%C3%A8s%20cool' 有效

来自计划的作业会话

utl_url.escape('Très cool') 返回 'Tr%E8s%20cool' 这是错误的

解决方案

utl_url.escape(PostPrameters, false, 'UTF-8')

【讨论】:

    【解决方案2】:

    程序SET_BODY_CHARSET:

    当媒体类型为 text 且未在 Content-Type 标头中指定字符集时,设置所有未来 HTTP 请求正文的默认字符集。

    此外,当您声明字符集 UTF-8 时,您无需转义。您只需要对 ASCII 或类似的字符进行转义。

    也许试试这个:

    PostPrameters := 'Très cool';    
    URL := utl_url.escape(URL,false,'UTF-8');
      
    HttpRequest := utl_http.begin_request(URL, 'POST', 'HTTP/1.1');    
    utl_http.set_authentication(HttpRequest, UserName, Password);      
    
    utl_http.set_header(HttpRequest, 'Content-Type','application/text; charset="UTF-8"');
    utl_http.set_header(HttpRequest, 'Content-Length',length(PostPrameters));
    utl_http.write_text(HttpRequest, PostPrameters);    
    

    【讨论】:

    • 感谢您的建议,但将内容类型更改为应用程序/文本会导致错误。
    • multipart/form-data 呢?
    • 实际上服务器只接受'application/x-www-form-urlencoded;'。这相当于我需要发送的命令:curl -X POST https://api.twilio.com/2010-04-01/Accounts/ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/Messages.json \ --data-urlencode "Body=Très sympa" \ --data-urlencode "From=+15017122661" \ --data-urlencode "To=+15558675310" \ -u ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:your_auth_token
    • 你试过了吗?主要跳过PostPrameters := utl_url.escape(PostPrameters);
    猜你喜欢
    • 1970-01-01
    • 2020-04-02
    • 2013-08-17
    • 1970-01-01
    • 1970-01-01
    • 2018-01-15
    • 2016-02-13
    • 2014-06-30
    • 1970-01-01
    相关资源
    最近更新 更多