- Este tópico contém 7 respostas, 2 vozes e foi atualizado pela última vez 6 anos, 5 meses atrás por José Laurindo Chiappa.
-
AutorPosts
-
9 de julho de 2018 às 8:23 pm #109315MottaParticipante
Alguém já passou por este problema ?
Prezado(a)s : Ao enviar um email em HTML pelo package SMTP o Oracle coloca um espaço em branco no meio de uma palavra do nada ,
algo como
Oracle coloca um espaço
fica
Oracle colo ca um espaçoA rotina do SMTP é basicamente a que a documentação do Oracle indica.
9 de julho de 2018 às 10:46 pm #109316José Laurindo ChiappaModeradorBlz ? Não, rigorosamente **** NUNCA **** vi o Oracle por conta própria colocar quebra de linha não : pra mim, a minha primeira e mais Provável Suposição é que vc tá montando o HTML dinamicamente e por BUG NA TUA ROTINA, em alguns casos fica alguma TAG html aberta/inválida… Pra DEBUGAR isso uma alternativa EXCELENTE é vc gravar o HTML num arquivo-texto e tentar abrir esse arquivo num editor de HTML….
A segunda Suposição é que vc NÃO esteja fazendo a conversão pra binário corretamente, confiando na conversão implícita e aí sabe Deus que tipo de resultado se obtém….
Como exemplo, veja a rotina abaixo que eu uso : ASSUMINDO a limitação de texto HTML menor que 32 Kb, ela funciona perfeitamente – tenta criar ela no teu banco e com ela enviar uma mensagem (TOMANDO O CUIDADO de incluir no texto da mensagem caracteres de carriage return E DE line feed se for Windows o servidor SMTP em questão), que DEVE funcionar okdoc ….
Segue :sistema@sistema-DESENV:SQL>get TESTE_PR_ENVIA_EMAIL.sql
1 create or replace procedure TESTE_PR_ENVIA_EMAIL (
2 WREMETENTE varchar2, — Remetente
3 WDESTINATARIO varchar2, — Destinatário
4 WDESTINATARIO_CC varchar2, — Com cópia
5 WASSUNTO varchar2,
6 WMENSAGEM clob
7 )
8 is
9 WSMTP varchar2(20) := ‘smtp.MINHAEMPRESA.com.br’; — Endereco IP do SMTP
10 WSMTP_USER varchar2(50) := ‘enviosistema@MINHAEMPRESA.com.br’; — Usuário autenticado no SMTP
11 WSMTP_USER_PASS varchar2(50) := ‘senhadousuárioSMTP’; — Senha do usuário SMTP
12 WCONN utl_smtp.connection; — Abre conexão SMTP e HTTP
13 WHTML varchar2(200) := ‘MIME-Version: 1.0’||utl_tcp.crlf||’Content-type: text/html; charset=iso-8859-1’||utl_tcp.crlf;
14 WBR varchar2(10) := chr(38)||’nbsp;’;
15 WRODAPE clob := ‘‘||WBR||WBR||WBR||’Este email foi enviado automaticamente pelos nossos sistemas informatizados.’||WBR||WBR||WBR||’ ‘;
16 BEGIN
17 — Abre conexão com um Servidor SMTP, porta padrão é 587
18 WCONN := utl_smtp.open_connection(WSMTP,587);
19 utl_smtp.helo(WCONN,WSMTP);
20 utl_smtp.command(WCONN,’AUTH LOGIN’);
21 utl_smtp.command(WCONN,utl_raw.cast_to_varchar2(utl_encode.base64_encode(utl_raw.cast_to_raw((WSMTP_USER)))));
22 utl_smtp.command(WCONN,utl_raw.cast_to_varchar2(utl_encode.base64_encode(utl_raw.cast_to_raw((WSMTP_USER_PASS)))));
23 utl_smtp.mail(WCONN,(”));
24 utl_smtp.rcpt(WCONN,(”));
25 if WDESTINATARIO_CC is not NULL then
26 utl_smtp.rcpt(WCONN,(”));
27 end if;
28 utl_smtp.open_data(WCONN);
29 utl_smtp.write_raw_data(WCONN,utl_raw.cast_to_raw(‘From:’ ||WREMETENTE ||utl_tcp.crlf));
30 utl_smtp.write_raw_data(WCONN,utl_raw.cast_to_raw(‘To:’ ||WDESTINATARIO ||utl_tcp.crlf));
31 utl_smtp.write_raw_data(WCONN,utl_raw.cast_to_raw(‘Cc:’ ||WDESTINATARIO_CC||utl_tcp.crlf));
32 utl_smtp.write_raw_data(WCONN,utl_raw.cast_to_raw(‘Subject:’||WASSUNTO ||utl_tcp.crlf));
33 UTL_smtp.write_raw_data(WCONN,utl_raw.cast_to_raw(WHTML));
34 utl_smtp.write_raw_data(WCONN,utl_raw.cast_to_raw(‘ ‘ ||utl_tcp.crlf));
35 utl_smtp.write_raw_data(WCONN,utl_raw.cast_to_raw(utl_tcp.crlf||WMENSAGEM));
36 utl_smtp.write_raw_data(WCONN,utl_raw.cast_to_raw(utl_tcp.crlf||WRODAPE));
37 utl_smtp.close_data(WCONN);
38 utl_smtp.quit(WCONN);
39 EXCEPTION
40 when OTHERS then
41 utl_smtp.quit(WCONN);
42 raise_application_error(-20011,’Não foi possível enviar o e-mail devido ao seguinte erro: ‘||sqlerrm);
43* END;
44 /Procedimento criado.
sistema@sistema-DESENV:SQL>
[]s
Chiappa
OBS :
a) logicamente, aqui usei um banco 10g pro meu exemplo – se fosse um banco 11g ou superior, eu TERIA que incluir também um ACL pra poder acessar servidores externos….
b) não deixe de checar por eventuais limites NO SERVIDOR DE EMAIL : muito embora em tese um texto html deveria ser capaz de ser exibido com qquer largura de linha, nada impede que teu servidor SMTP por qquer motivo restrinja linesize do html a enviar – NADA A VER com o banco Oracle em si e TUDO A VER com seu servidor SMTP…
10 de julho de 2018 às 12:45 am #109317MottaParticipanteValeu. pela resposta.
Salvo um html na pasta utl padrão , leio este arquivo e jogo para um CLOB.
O erro ocorre para o nosso dominio na empresa e também no meu particular (Yahoo).
Esta SP chama outra que manda o email , esta do email é basicamente a da documentação Oracle , funciona beleza mas estava colocando este espaço antes.
Pesquisei alguns sites e vi relação com um buffer limitado a 1000 caracteres , não achei nenhum parâmetro para aumentar isto.
Talvez a solução seja varrer o blob de 1000 em 1000 registros e tratar isto , pegar uma palavra no meio quando na posição 1000.
Estranho paca.
Segue a SP de envio
create or replace PROCEDURE ENVIA_EMAIL_CLOBH (ds_email_origem_w varchar2,
ds_email_destino_p varchar2,
ds_assunto varchar2,
p_attach_clob IN CLOB DEFAULT NULL,
p_httm in varchar2 default 'S',
p_log out varchar2,
p_nome_destino in varchar2 default null) isl_step PLS_INTEGER := 900;--12000;-- make sure you set a multiple of 3 not higher than 24573 (doc Oracle)
ds_smtp_w varchar2(20) := '......';
/* Abre conex?o SMTP e HTTP */
CONEXAO UTL_SMTP.CONNECTION;
-- fixar este envio por segurança
vs_origem varchar2(100) := ds_email_origem_w;
--
vs_para varchar2(100);
vs_cc varchar2(100);
--PROCEDURE send_header(name IN VARCHAR2, header IN VARCHAR2) AS
BEGIN
UTL_SMTP.WRITE_DATA(CONEXAO, name || ': ' || header || UTL_TCP.CRLF);
END;BEGIN
/* Abre conex?o com um Servidor SMTP(Simple Mail Transfer Protocol), porta padr?o SMTP e 25 */
CONEXAO := utl_smtp.open_connection (ds_smtp_w,25);
UTL_SMTP.HELO (CONEXAO, ds_smtp_w); /* Endereco do servidor de SMTP */
--utl_smtp.command (CONEXAO, 'AUTH LOGIN');
--utl_smtp.command (CONEXAO, utl_raw.cast_to_varchar2(utl_encode.base64_encode(utl_raw.cast_to_raw((ds_user_id_w)))));
--UTL_SMTP.COMMAND (CONEXAO, UTL_RAW.CAST_TO_VARCHAR2(UTL_ENCODE.BASE64_ENCODE(UTL_RAW.CAST_TO_RAW((DS_SENHA_SMTP_W)))));UTL_SMTP.MAIL (CONEXAO, ('')); /* E-mail de quem esta mandando */
-- se estiver em lista separado por ";" manda para o 1º como "para" e para o 2º como CC (copia)
/* Para quem vou mandar */
IF INSTR(ds_email_destino_p,';') = 0 THEN
vs_para := ds_email_destino_p;
UTL_SMTP.RCPT (CONEXAO, ('')); /* Para quem vou mandar */
ELSE
vs_para := SUBSTR(ds_email_destino_p,1,INSTR(ds_email_destino_p,';')-1);
vs_cc := SUBSTR(ds_email_destino_p,INSTR(ds_email_destino_p,';')+1,length(ds_email_destino_p));
UTL_SMTP.RCPT (CONEXAO, ('')); /* Para quem vou mandar original */
UTL_SMTP.RCPT (CONEXAO, ('')); /* Para quem vou mandar copia */
END IF;
UTL_SMTP.OPEN_DATA(CONEXAO);If upper(p_httm) 'S' Then
send_header('Subject','=?iso-8859-1?Q?' ||UTL_RAW.CAST_TO_VARCHAR2(UTL_ENCODE.QUOTED_PRINTABLE_ENCODE(UTL_RAW.CAST_TO_RAW(ds_assunto))));
Else
send_header('Subject','=?iso-8859-1?Q?' ||UTL_RAW.CAST_TO_VARCHAR2(UTL_ENCODE.QUOTED_PRINTABLE_ENCODE(UTL_RAW.CAST_TO_RAW(ds_assunto)))|| '?=');
end if;If upper(p_httm) 'S' Then
UTL_SMTP.write_data(CONEXAO, 'Content-Type: text/html; charset="UTF-8"' || utl_tcp.CRLF);
Else
UTL_SMTP.write_data(CONEXAO, 'Content-Type: text/html; charset="UTF-8"' || utl_tcp.CRLF );
end if;send_header('From',ds_email_origem_w);
--se denominou o destino formata o envio , senão vai o proprio email
--tratamento diferente do "from" pois este é em geral dinamico
--feito pela stored procedure chamadora
if trim(p_nome_destino) is null then
send_header('To',vs_para);
else
send_header('To','"'||trim(p_nome_destino)||'" ');
end if;If Trim(vs_cc) is not null Then--copia (nao formata o destino)
send_header('CC',vs_cc);
end if;FOR i IN 0 .. TRUNC((DBMS_LOB.getlength(p_attach_clob) - 1 )/l_step)
FOR i IN 0 .. TRUNC((DBMS_LOB.getlength(p_attach_clob) - 1 )/l_step)
LOOP
UTL_SMTP.WRITE_DATA(CONEXAO, DBMS_LOB.substr(p_attach_clob, l_step, i * l_step + 1));
END LOOP;UTL_SMTP.CLOSE_DATA(CONEXAO);
UTL_SMTP.QUIT (CONEXAO);
Exception
when OTHERS then
utl_smtp.quit (conexao);
p_log := 'Erro: ' || SQLERRM;
END ENVIA_EMAIL_CLOBH;10 de julho de 2018 às 9:19 pm #109318José Laurindo ChiappaModeradorAcho que entendi o seu ‘problema’ : na verdade não tem *** NADA A VER *** com o database Oracle (NEM DE LONGE é o ‘database Oracle enfiando brancos aleatoriamente, como vc deu a entender) e ** TUDO A VER ** com o protocolo SMTP, okdoc ?? NADA ESTRANHO, longe disso…
Cfrme https://www.emailonacid.com/blog/article/email-development/line-length-in-html-email/ explica, de acordo com a norma [RFC2821] , esse protocolo de comunicação IMPÕE um limite de 1000 caracteres numa linha aí já inclusos os eventuais caracteres de controle/fluxo de linha como linefeeds/carriage returnos e etc…. No caso eu não tinha caído nisso porque eu mando TEXTOS (ie, cartas, memorandos, avisos, etc) a serem lidos por HUMANOS no corpo do email, e pra esse tipo de uso não faz sentido uma linha tão grande, é ilegível por um humano, não cabe nem em monitor nem em janela de editor de texto normal…. O meu contra-exemplo, usando a minha rotina :
testenv@SISTEMA:SISTEMA-DESENV:SQL>l
1 DECLARE
2 v_str varchar2(4000);
3 BEGIN
4 v_str := lpad(‘A’, 500, ‘*’) || lpad(‘B’, 500, ‘!’) || lpad(‘C’, 500, ‘@’) || lpad(‘D’, 499, ‘$’) || ‘Z’;
5 TESTE_PR_ENVIA_EMAIL(‘financeiro@SISTEMA.com.br’, ‘jlchiappa@gmail.com’, ‘jlchiappa@yahoo.com.br’, ‘Assunto:TESTE’, v_str);
6* END;
testenv@SISTEMA:SISTEMA-DESENV:SQL>/Procedimento PL/SQL concluído com sucesso.
==> O que resultou pra mim no email que recebi :
*******************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************A!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !B@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@C$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ $$$DZ
(talvez o Forum aqui enfie umas quebras de linha por conta própria, mas na verdade o que temos aqui é uma só longuíssima linha mas com espaço a cada 1000 caracteres, OBEDECENDO aos ditames pro protocolo SMTP)…
Já que é algo IMPOSTO por padrões externos ao database Oracle, quais workarounds adotar ?
=> como não faz sentido enviar um texto a ser lido por um humano numa só longuíssima linha, eu SUPONHO que na verdade essa informação são DADOS a serem lidos/interpretados por um sistema informatizado, correto ? Sendo isso, minha Sugestão seria vc enviar esses dados como um ARQUIVO ANEXO ao email : https://oracle-base.com/articles/misc/email-from-oracle-plsql#clob tem um exemplo de como fazer isso via UTL_SMTP, é bem simples a alteração necessária….
ou
=> se REALMENTE a informação vai ser consumida por um HUMANO, please insira os linebreaks necessários a cada x caracteres, onde x é um número bem inferior a 1000….
[]s
Chiappa
10 de julho de 2018 às 11:27 pm #109320MottaParticipanteMais uma vez grato.
11 de julho de 2018 às 12:32 am #109323José Laurindo ChiappaModeradorOk, espero ter ajudado e desfeito a ‘estranheza’ / explicado a causa do comportamento….
E reforço a idéia de ANEXAR num arquivo se teus dados realmente PRECISAM estar em linhas tão longas : mesmo usando os caracteres html corretos de quebra de linha, tal como https://github.com/adam-p/markdown-here/issues/130 e https://stackoverflow.com/questions/46979198/how-to-wrap-long-text-in-html-emails (entre vários outros) indicam, clientes de email podem SIM apresentar problemas de exibição com html contendo linhas anormalmente longas …
[]s
Chiappa
12 de julho de 2018 às 5:14 pm #109331MottaParticipanteVamos pelo mais simples , vamos mandar link de imagem.
12 de julho de 2018 às 6:28 pm #109335José Laurindo ChiappaModeradorAinda melhor, se tem a possibilidade de incluir um link no teu email apontando pro local onde os dados estão, melhor ainda : muitas vezes vc está mandando emails pra usuários externos da Empresa, nem sempre há a chance de se ter um servidor acessível onde os dados residam acessível via link html/url, se vc tem a possibilidade, maravilha…
[]s
Chiappa
OBS : só estranhei quando vc disse que o link será ‘de imagem’ : é uma imagem/um arquivo contendo alguma imagem num formato gráfico qquer que vc quer passar no email ? Se sim, se o tamanho do arquivo de imagem não for estrondosamente grande, por que não anexar ele no email ?
-
AutorPosts
- Você deve fazer login para responder a este tópico.