Erro na Formatação de Email HTML que é Enviado c/ UTL_SMTP

Dúvidas, dicas e truques de PL/SQL. Aqui também vão assuntos relacionados a pacotes, triggers, funções, Java-Stored Procedures, etc
Responder
prsilva
Rank: Estagiário Pleno
Rank: Estagiário Pleno
Mensagens: 6
Registrado em: Seg, 24 Mar 2014 1:50 pm

Boa tarde!

Envio notificações por e-mail pelo banco de dados através da package UTL_SMTP. O email é enviado em formato HTML, com o corpo todo na fonte Arial tamanho 9, porém em alguns casos, o e-mail chega com fonte Times ou tamanho 12.
Verifiquei que até onde consigo enxergar, o que é enviado pelo comando UTL_SMTP.WRITE_RAW_DATA(c, UTL_RAW.CAST_TO_RAW(v_buffer)); está no formato correto, porém daí pra frente se perde.
Notei também que no meu e-mail, quando recebo, habilito o Inspecionar Elemento do Chrome e copio o HTML para o textpad e noto que no caracter 1046 tem uma quebra de linha, o que ocorre nesses casos de quebrar bem na tag font, alterando nos casos o fonte ou o tamanho.
Ouvi falar em tamanho do buffer do banco, que talvez esteja limitado a 1000 caracteres.
Pergunto, essa quebra tem haver com o tamanho do buffer? Se sim, como faço para alterar esse tamanho? Alguma sugestão para a resolução do problema?
Estou utilizando o banco Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production e PL/SQL PL/SQL Release 11.2.0.1.0 - Production.
Abaixo o código da procedure de envio de e-mail:

Selecionar tudo

PROCEDURE SEND_EMAIL(p_email_from IN varchar2,
                     p_rcpt_to    IN varchar2,
                     p_title      IN varchar2 DEFAULT 'no subject',
                     p_body       IN clob,
                     p_cd_anexo   in number default null) IS

  c utl_smtp.connection;

  v_body_você varchar2(32000);

  v_body CLOB;

  v_global_name varchar2(10) := BUSCA_GLOBAL_NAME;

  P_USERNAME VARCHAR2(200) := 'XXXXX'-- Endereço de e-mail para autenticacao no SMTP Server
  P_PASSWORD VARCHAR2(200) := 'XXXXX'--Senha do e-mail

BEGIN

  IF (instr(p_email_from, '@') > 0) AND (instr(p_rcpt_to, '@') > 0) THEN
    c := utl_smtp.open_connection(SMTP_SERVER, 587);
    utl_smtp.helo(c, DOMAIN);
    /*realiza autenticacao*/
    UTL_SMTP.COMMAND(c, 'AUTH LOGIN');
    UTL_SMTP.COMMAND(c,
                     UTL_RAW.CAST_TO_VARCHAR2(UTL_ENCODE.BASE64_ENCODE(UTL_RAW.CAST_TO_RAW(P_USERNAME))));
    UTL_SMTP.COMMAND(c,
                     UTL_RAW.CAST_TO_VARCHAR2(UTL_ENCODE.BASE64_ENCODE(UTL_RAW.CAST_TO_RAW(P_PASSWORD))));
    /*Termino autenticacao*/
  
    --
    -- ENVIANDO E-MAIL  -- INÍCIO
  
     utl_smtp.mail(c, p_email_from );
    utl_smtp.rcpt(c, p_rcpt_to);
    utl_smtp.open_data(c);
    v_body_você := replace(p_body,
                         'Subject:',
                         'Subject: ' || BUSCA_GLOBAL_NAME );
  
    IF upper(dbms_lob.substr(p_body, 5, 1)) = 'FROM:' THEN
      v_body := v_body_você;
    ELSE
      BEGIN
        -- montando mensagem de acordo com padrão
        DBMS_LOB.createtemporary(v_body, false);
        DBMS_LOB.writeappend(v_body,
                             7 + length(p_email_from) + 1 +
                             length(utl_tcp.CRLF),
                             'From: "' || p_email_from || '"' ||
                             utl_tcp.CRLF);
        DBMS_LOB.writeappend(v_body,
                             5 + length(p_rcpt_to) + 1 +
                             length(utl_tcp.CRLF),
                             'To: "' || p_rcpt_to || '"' || utl_tcp.CRLF);
        DBMS_LOB.writeappend(v_body,
                             9 + length(p_title /*v_title*/) +
                             length(utl_tcp.CRLF),
                             'Subject:' || p_title /*v_title*/
                             || utl_tcp.CRLF);
        DBMS_LOB.writeappend(v_body, length(utl_tcp.CRLF), utl_tcp.CRLF);
        DBMS_LOB.append(v_body, v_body_você);
        DBMS_LOB.writeappend(v_body, length(utl_tcp.CRLF), utl_tcp.CRLF);
      EXCEPTION
        WHEN OTHERS THEN
          dbms_output.put_line('ERRO =>' || sqlerrm);
          v_body := v_body_você;
      END;
    END IF;
    -- Um loop é necessário pois um RAW tem limite do tamanho do VARCHAR2 (32767)
    DECLARE
      v_size   PLS_INTEGER := 32767;
      v_buffer VARCHAR2(32767);
      v_offset PLS_INTEGER := 1;
    BEGIN
      LOOP
        DBMS_LOB.read(v_body, v_size, v_offset, v_buffer);
        v_offset := v_offset + v_size;
        dbms_output.put_line('v_buffer: ' || v_buffer);
        UTL_SMTP.WRITE_RAW_DATA(c, UTL_RAW.CAST_TO_RAW(v_buffer));
      END LOOP;
    EXCEPTION
      WHEN NO_DATA_FOUND THEN
        NULL;
    END;
  
    if p_cd_anexo is not null then
      gera_anexo(c, p_cd_anexo);
    end if;
  
    utl_smtp.close_data(c);
    utl_smtp.quit(c);
  
    IF DBMS_LOB.istemporary(v_body) > 0 THEN
      DBMS_LOB.freetemporary(v_body);
    END IF;
  END IF;

EXCEPTION
  WHEN utl_smtp.transient_error OR utl_smtp.permanent_error THEN
    dbms_output.put_line('ERRO send_mail =>' || sqlerrm);
    utl_smtp.quit(c);
  
  WHEN OTHERS THEN
    utl_smtp.quit(c);
END; -- Procedure
Desde já agradeço a atenção.
Avatar do usuário
fbifabio
Moderador
Moderador
Mensagens: 199
Registrado em: Ter, 22 Fev 2011 1:51 pm
Localização: São Paulo - SP
Contato:
Fábio Prado
www.fabioprado.net

@prsilva

A package UTL_SMTP tem muitos recursos e muitas configurações, portanto, pouca gente tem conhecimentos avançados sobre ela. Seus problemas provavelmente serão resolvidos se você aprender a configurá-la (via programação) de acordo com a sua necessidade. Sugiro que você pesquise documentações sobre ela. Seguem abaixo alguns links:

- http://docs.oracle.com/cd/B19306_01/app ... u_smtp.htm
- http://docs.oracle.com/cd/E11882_01/app ... ARPLS71459
- http://www.oracle-base.com/articles/mis ... -plsql.php

[]s
Responder
  • Informação