Banco de Dados - Oracle

Enviando e-mail utilizando o Oracle

Deve-se utilizar as packages UTL_SMTP e UTL_TCP. Para empregar estas packages internas e chamá-las eventualmente em todos os lugares aplicáveis nos sistemas poderá ser escrita uma rotina...

por Leandro Castello Eschiavi



Deve-se utilizar as packages UTL_SMTP e UTL_TCP. Para empregar estas packages internas e chamá-las eventualmente em todos os lugares aplicáveis nos sistemas poderá ser escrita uma rotina. As mensagens poderão ser enviadas sempre que um evento ocorrer ou poderão ser programadas como um JOB.

O que você vai necessitar para executar esta tarefa.

1. O nome de um servidor de e-mail ou o endereço IP. Este servidor poderá ser de uma intranet ou de um serviço remoto que esteja disponível. A palavra "localhost" pode ser usada para chamar o Oracle a usar o serviço "default" para o Sistema Operacional (SMTP).

2. O Sistema Operacional deverá suportar os serviços de SMTP. A maioria dos Unix do mercado suportam este serviço. Para o Windows 2000, verificar se o serviço de SMTP está disponível.

3. O serviço irá utilizar uma porta para comunicar-se com o SMTP. Normalmente o valor "default" da porta é o 25.

4. O banco de dados deverá ter os serviços de Java habilitados. A opção do Jserver deverá ser instalada usando os scripts (initjvm.sql e initplsj.sql).

5. A package UTL_SMTP deverá existir na base e o seu "owner" deverá ser o usuário SYS.

Descrição das rotinas da package UTL_SMTP:

UTL_SMTP.OPEN_CONNECTION
Abre uma conexão para um servidor de SMTP. UTL_SMTP.HELLO: Inicializa o serviço "handshake".

UTL_SMTP.MAIL
Inicializa a transação de envio do e-mail para o servidor.

UTL_SMTP.RCPT
Especifica o nome do recipiente.

UTL_SMTP.DATA
Especifica o corpo da mensagem.

UTL_SMTP.OPEN_DATA / UTL_SMTP.WRITE_DATA / UTL_SMTP.CLOSE_DATA
Um modo mais refinado de especificar o corpo da mensagem com maiores controles.

UTL_SMTP.VRFY
Verifica a validade dos endereços.

UTL_SMTP.QUIT
Termina a sessão e desconecta do servidor de SMTP.

create or replace procedure p_sendmail (  
      from_name     varchar2                    :="seu e-mail"
      ,to_name       varchar2                    :="e-mail"
      ,subject       varchar2                    :="Mensagem Oracle"
      ,message       varchar2                    :="Mensagem do Servidor Oracle"
      ,max_size      number   default 9999999999
      ,filename1  in varchar2                    :="/u41/spool/email/enviados/P183507.txt"
      ,filename2  in varchar2                    :="/u41/spool/email/enviados/P182303.txt"
      ,filename3  in varchar2                    :="/u41/spool/email/enviados/P182552.txt"
      ,debug         number   default 0 ) 

is

  v_smtp_server                          varchar2(30)                              :="10.0.8.98";
  v_smtp_server_port                     number                                    := 21;
  v_directory_name                       varchar2(100);
  v_file_name                            varchar2(100);
  v_line                                 varchar2(1000); 
  crlf                                   varchar2(2)                               := chr(13) || 
chr(10);
  mesg                                   varchar2(32767);

  conn                                   UTL_SMTP.CONNECTION;                                        

  type varchar2_table  is table of       varchar2(200) index by binary_integer;
  file_array                             varchar2_table;
  
  i                                      binary_integer;
  v_file_handle                          utl_file.file_type;
  v_slash_pos                            number;
  mesg_len                               number;
  mesg_too_long                          exception;
  invalid_path                           exception;
  mesg_length_exceeded                   boolean                                   := false;


begin

   -- Carregando os arquivos dentro do ARRAY
   -- --------------------------------------- 
   file_array(1) := filename1;
   file_array(2) := filename2;
   file_array(3) := filename3;

   -- Abrindo Conexão SMTP e HTTP
   -- ----------------------------
   conn  := utl_smtp.open_connection( v_smtp_server, v_smtp_server_port );

   -- Comunicando SMTP
   -- ------------------
   utl_smtp.helo( conn, v_smtp_server );
   utl_smtp.mail( conn, from_name );
   utl_smtp.rcpt( conn, to_name );
   utl_smtp.open_data ( conn );

   -- Criando Cabeça do E-mail
   -- -----------------------------------
   mesg:= "Date: "    || TO_CHAR( SYSDATE, "dd Mon yy hh24:mi:ss" )                     || crlf ||
          "From: "    || from_name                                                      || crlf ||
          "Subject: " || subject                                                        || crlf ||
          "To: "      || to_name                                                        || crlf ||
          "Mime-Version: 1.0"                                                           || crlf ||
          "Content-Type: multipart/mixed; boundary="DMW.Boundary.605592468""            || crlf ||
          ""                                                                            || crlf ||
          "This is a Mime message, which your current mail reader may not"              || crlf ||
          "understand. Parts of the message will appear as text. If the remainder"      || crlf ||
          "appears as random characters in the message body, instead of as"             || crlf ||
          "attachments, then you""ll have to extract these parts and decode them"       || crlf ||
          "manually."                                                                   || crlf ||
          ""                                                                            || crlf ||
          "--DMW.Boundary.605592468"                                                    || crlf ||
          "Content-Type:              text/plain; name="message.txt"; charset=US-ASCII" || crlf ||
          "Content-Disposition:       inline;     filename="message.txt""               || crlf ||
          "Content-Transfer-Encoding: 7bit"                                             || crlf ||
          ""                                                                            || crlf ||
          message                                                                       || crlf ;

   mesg_len := length(mesg);

   if mesg_len> max_size then
      mesg_length_exceeded := true;
   end if;

   utl_smtp.write_data ( conn, mesg );

   -- Anexando Arquivos
   -- ------------------
   for i in  1..3 loop

       -- Sair se ultrapassar o tamanho de mensagem
       -- -----------------------------------------
       exit when mesg_length_exceeded;          

       if file_array(i) is not null then

          begin
              
             -- Localiza a "/" ou "\" no caminho
             -- ---------------------------------
             v_slash_pos := instr(file_array(i), "/", -1 );

             if v_slash_pos = 0 then
                v_slash_pos := instr(file_array(i), "\", -1 ); -- Valor Retornado = 3

             end if;

             -- Separa o arquivo do diretório
             -- ------------------------------
             v_directory_name := substr(file_array(i), 1, v_slash_pos - 1);
             v_file_name      := substr(file_array(i), v_slash_pos + 1 );

             -- Abrir Arquivo
             -- --------------
             v_file_handle := utl_file.fopen(v_directory_name,v_file_name,"w");

             -- Gera a linha MIME boundary
             -- --------------------------
             mesg := crlf || "--DMW.Boundary.605592468" || crlf ||
             "Content-Type:              application/octet-stream; name=    "v_file_name""  || crlf ||
             "Content-Disposition:       attachment;               filename="v_file_name""  || crlf ||
             "Content-Transfer-Encoding: 7bit"                                              || crlf || 
crlf ;

             mesg_len := mesg_len + length(mesg);
             utl_smtp.write_data ( conn, mesg );

             -- Anexa o conteúdo do arquivo ao corpo da mensagem
             -- ------------------------------------------------

             loop
   
                 utl_file.get_line(v_file_handle, v_line);
   
                 if mesg_len + length(v_line)> max_size then

                    mesg := "*** truncado ***" || crlf;

                    utl_smtp.write_data ( conn, mesg );

                    mesg_length_exceeded := true;

                    raise mesg_too_long;

                 end if;

                 mesg := v_line || crlf;

                 utl_smtp.write_data ( conn, mesg );
   
                 mesg_len := mesg_len + length(mesg);

             end loop;

          exception

             when utl_file.invalid_path then
                 if debug> 0 then
                    dbms_output.put_line("Erro anexando arquivo ! "|| file_array(i));
                 end if;              

             -- Todas EXCEPTIONS ignoradas
             when others then null;

          end;

          mesg := crlf;

          utl_smtp.write_data ( conn, mesg );

          -- Fecha Arquivo
          -- --------------
          utl_file.fclose(v_file_handle);

        end if;

   end loop;

   -- Fechando a Cabeça do E-mail
   -- ----------------------------
   mesg := crlf || "--DMW.Boundary.605592468--" || crlf;
   utl_smtp.write_data ( conn, mesg );

   -- Fechando conexão SMTP
   -- -----------------------
   utl_smtp.close_data( conn );
   utl_smtp.quit( conn );

end;
Leandro Castello Eschiavi

Leandro Castello Eschiavi - Desenv. Sistemas Comerciais
Casas Pernambucanas