UTL_SMTP: Sending Accents

Asked

Viewed 1,664 times

1

Hello,

I am using Oracle XE 11.2 to send emails using the UTL_SMTP package, but whenever there are accents to the subject or message, it is replaced by a "?". Here’s what I got:

I have a protocol that contains the parameters for sending email:

v_Mail_Conn := utl_smtp.Open_Connection(v_smtp, 25);
 --autenticacao
 utl_smtp.command( v_Mail_Conn, 'AUTH LOGIN'); 
 utl_smtp.command( v_Mail_Conn, utl_raw.cast_to_varchar2( utl_encode.base64_encode( utl_raw.cast_to_raw( v_username ))) ); 
 utl_smtp.command( v_Mail_Conn, utl_raw.cast_to_varchar2( utl_encode.base64_encode( utl_raw.cast_to_raw( v_pwd ))) ); 


 --Conexao
 utl_smtp.Helo(v_Mail_Conn, v_smtp);
 utl_smtp.Mail(v_Mail_Conn, v_from);
 utl_smtp.Rcpt(v_Mail_Conn, v_to);

--MENSAGEM SEM ANEXO TEXTO PLANO
 /*utl_smtp.Data(v_Mail_Conn,
   'Date: '   || to_char(sysdate, 'Dy, DD Mon YYYY hh24:mi:ss') || crlf ||
   'From: '   || v_from || crlf ||
   'Subject: '|| v_assunto || crlf ||
   'To: '     || v_to || crlf ||
   crlf || v_message || ''
 );*/

--MENSAGEM SEM ANEXO HTML
utl_smtp.Data(v_Mail_Conn,
    'Date: '   || to_char(sysdate, 'Dy, DD Mon YYYY hh24:mi:ss') || crlf ||
    'From: '   || v_from || crlf ||
    'Subject: '|| v_assunto || crlf ||
    'To: '     || v_to || crlf ||

    'MIME-Version: 1.0'|| crlf ||    -- Use MIME mail standard
    'Content-Type: multipart/mixed;'|| crlf ||
    ' boundary="-----SECBOUND"'|| crlf ||
    crlf ||

    '-------SECBOUND'|| crlf ||
    'Content-Type: text/html; charset="UTF-8"'|| crlf ||
    'Content-Transfer-Encoding: 8bit'|| crlf ||
    crlf ||
        v_message ||
    crlf);

From my research, I’ve noticed that the problem may be in this part:

utl_smtp.Data(v_Mail_Conn,
        'Date: '   || to_char(sysdate, 'Dy, DD Mon YYYY hh24:mi:ss') || crlf ||
        'From: '   || v_from || crlf ||
        'Subject: '|| v_assunto || crlf ||
        'To: '     || v_to || crlf ||

        'MIME-Version: 1.0'|| crlf ||    -- Use MIME mail standard
        'Content-Type: multipart/mixed;'|| crlf ||
        ' boundary="-----SECBOUND"'|| crlf ||
        crlf ||

        '-------SECBOUND'|| crlf ||
        'Content-Type: text/html; charset="UTF-8"'|| crlf ||
        'Content-Transfer-Encoding: 8bit'|| crlf ||
        crlf ||
            v_message ||
        crlf);

Because I am defining 8bit and UTF-8, but even changing the charset it still keeps sending the "?" as message.

I researched about the UTL_ENCODE.QUOTED_PRINTABLE_ENCODE and set content-transfer-encoding as quoted-printable, but still continue with the error.

These are the language parameters of NLS:

NLS_LANGUAGE    AMERICAN
NLS_TERRITORY   AMERICA
NLS_CURRENCY    $
NLS_ISO_CURRENCY    AMERICA
NLS_NUMERIC_CHARACTERS  . 
NLS_CALENDAR    GREGORIAN
NLS_DATE_FORMAT DD-MON-RR
NLS_DATE_LANGUAGE   AMERICAN
NLS_CHARACTERSET    AL32UTF8
NLS_SORT    BINARY
NLS_TIME_FORMAT HH.MI.SSXFF AM
NLS_TIMESTAMP_FORMAT    DD-MON-RR HH.MI.SSXFF AM
NLS_TIME_TZ_FORMAT  HH.MI.SSXFF AM TZR
NLS_TIMESTAMP_TZ_FORMAT DD-MON-RR HH.MI.SSXFF AM TZR
NLS_DUAL_CURRENCY   $
NLS_NCHAR_CHARACTERSET  AL16UTF16
NLS_COMP    BINARY
NLS_LENGTH_SEMANTICS    BYTE
NLS_NCHAR_CONV_EXCP FALSE
  • 1

    How are the "Parameters" of language and territory ? https://docs.oracle.com/cd/E18283_01/appdev.112/e10766/tdddg_globalization.htm#CACIIJGI

  • 1

    The parameters are in the question. As an interim solution I encoded all accents in html, it seems to work but is not the best thing

  • I don’t think it’s a bad solution, because the email looks better , what we use in the company where I work is just text I started doing in html. Tried to switch the Session language to Portuguese or CHARACTERSET ?

  • So, the big problem is that we also had accent errors in the application that were fixed, I don’t know if changing the language can result in the return of problems, I think I’ll leave with the html Markup.

2 answers

2

You can create a Function that you pass a string and Function returns the string with the conversion in the default Ascii Code >127.

Example:

create or replace function converte(p_texto in varchar2) return varchar2 is
  RESULT LONG := text;   
begin
   RESULT := REPLACE(RESULT, 'À', '&Agrave');
   RESULT := REPLACE(RESULT, 'à', 'à');
   RESULT := REPLACE(RESULT, 'Ã', 'Ã');
   RESULT := REPLACE(RESULT, 'ã', 'ã');
   RESULT := REPLACE(RESULT, 'Õ', 'Õ');
   RESULT := REPLACE(RESULT, 'õ', 'õ');
   RETURN(RESULT);
end;

Using:

DECLARE
  v_teste long;
BEGIN

  v_teste := converte('BALÃO');      

END;

Send so by UTL_SMPT that will work.
Some sites have conversion table.
Link: [http://www.lsi.usp.br/~help/html/iso.html]
Link: [http://blog.desenvolvedorsa.com/tabela-de-conversao-de-caracteres-especiais/]

2


I had the same problem and I was able to solve it in the same way directed by Davi Melo, but I needed some adjustments and so I decided to post this answer to help someone else who goes through it.

Follows how my process for sending e-mail:

create or replace PROCEDURE SEND_EMAIL
( v_From    in varchar2,
  v_Recipient in varchar2,
  v_Subject   in varchar2,
  v_Mail_Message   in varchar2)
is
  v_Mail_Host VARCHAR2(30) := 'mail.server.com.br';
  v_Mail_Conn utl_smtp.Connection;
  crlf        VARCHAR2(2)  := chr(13)||chr(10);
BEGIN
 v_Mail_Conn := utl_smtp.Open_Connection(v_Mail_Host, 25);
 utl_smtp.Helo(v_Mail_Conn, v_Mail_Host);
 utl_smtp.Mail(v_Mail_Conn, v_From);
 utl_smtp.Rcpt(v_Mail_Conn, v_Recipient);
 utl_smtp.Data(v_Mail_Conn,
   'Date: '   || to_char(sysdate, 'Dy, DD/MM/YYYY HH24:mi:ss') || crlf ||
   'From: '   || v_From || crlf ||
   'Subject: '|| v_Subject || crlf ||
   'To: '     || v_Recipient || crlf ||

   'MIME-Version: 1.0'|| crlf ||    -- Use MIME mail standard
   'Content-Type: text/html;charset=UTF-8'|| crlf ||
    crlf ||
        CONVERT_SPECIAL_CHAR(v_Mail_Message) ||
    crlf);
 utl_smtp.Quit(v_Mail_Conn);
EXCEPTION
 WHEN utl_smtp.Transient_Error OR utl_smtp.Permanent_Error then
  raise_application_error(-20000, 'Não foi possível enviar o e-mail.', TRUE);
 WHEN OTHERS THEN
  raise_application_error(-20001,
      'Ocorreu o seguinte erro: ' || sqlerrm);
END;

In the above precedent I called the CONVERT_SPECIAL_CHAR function to convert the special characters, which was the same suggested by @Davidmelo, with a simple correction. Follows below the function:

create or replace function CONVERT_SPECIAL_CHAR(p_texto in varchar2) RETURN VARCHAR2
AS
  v_result VARCHAR2(32767);   
begin
   v_result := p_texto;
   v_result := REPLACE(v_result, 'À', chr(38)||'Agrave;');
   v_result := REPLACE(v_result, 'à', chr(38)||'agrave;');
   v_result := REPLACE(v_result, 'Ã', chr(38)||'Atilde;');
   v_result := REPLACE(v_result, 'ã', chr(38)||'atilde;');
   v_result := REPLACE(v_result, 'Õ', chr(38)||'Otilde;');
   v_result := REPLACE(v_result, 'õ', chr(38)||'otilde;');
   v_result := REPLACE(v_result, 'á', chr(38)||'aacute;');
   v_result := REPLACE(v_result, 'Á', chr(38)||'Aacute;');
   v_result := REPLACE(v_result, 'é', chr(38)||'eacute;');
   v_result := REPLACE(v_result, 'É', chr(38)||'Eacute;');
   v_result := REPLACE(v_result, 'í', chr(38)||'iacute;');
   v_result := REPLACE(v_result, 'Í', chr(38)||'Iacute;');
   v_result := REPLACE(v_result, 'ó', chr(38)||'oacute;');
   v_result := REPLACE(v_result, 'Ó', chr(38)||'Oacute;');
   v_result := REPLACE(v_result, 'ú', chr(38)||'uacute;');
   v_result := REPLACE(v_result, 'Ú', chr(38)||'Uacute;');
   v_result := REPLACE(v_result, 'â', chr(38)||'acirc;');
   v_result := REPLACE(v_result, 'Â', chr(38)||'Acirc;');
   v_result := REPLACE(v_result, 'ê', chr(38)||'ecirc;');
   v_result := REPLACE(v_result, 'Ê', chr(38)||'Ecirc;');
   v_result := REPLACE(v_result, 'ô', chr(38)||'ocirc;');
   v_result := REPLACE(v_result, 'Ô', chr(38)||'Ocirc;');
   v_result := REPLACE(v_result, 'ç', chr(38)||'ccedil;');
   v_result := REPLACE(v_result, 'Ç', chr(38)||'Ccedil;');
   v_result := REPLACE(v_result, 'ü', chr(38)||'uuml;');
   v_result := REPLACE(v_result, 'Ü', chr(38)||'Uuml;');
   RETURN(v_result);
end;

Note that texts should always be set to HTML since we are using :

'Content-Type: text/html;charset=UTF-8'

Finally an example to test the function and process:

Declare
  text varchar2(32000) := '<html><head></head><title>Título</title><body>' ||
  '<p>Olá... <b>Teste e-mail HTML</b>,</p>' ||
  '<p>Testes acentos: áÁ ãà õ á ó é úÚ Àà òÒ...</p> </body></html>';
BEGIN
  SEND_EMAIL('[email protected]', '[email protected]', 'Assunto do e-mail', text); 
END;

Browser other questions tagged

You are not signed in. Login or sign up in order to post.