Foros del Web » Programación para mayores de 30 ;) » Bases de Datos General » Oracle »

Procedimiento de envio de correo

Estas en el tema de Procedimiento de envio de correo en el foro de Oracle en Foros del Web. Hola, una vez mas recurro a este foro para ver si me sacais otra vez las castañas del fuego... He encontrado en la red el ...
  #1 (permalink)  
Antiguo 24/06/2008, 09:35
 
Fecha de Ingreso: marzo-2005
Mensajes: 189
Antigüedad: 19 años
Puntos: 0
Procedimiento de envio de correo

Hola, una vez mas recurro a este foro para ver si me sacais otra vez las castañas del fuego...

He encontrado en la red el siguiente procedimiento PL/SQL para enviar correos desde Oracle cuando se está agotando el espacio en un tablespace:

CREATE OR REPLACE PROCEDURE SEND_MAIL(SENDER IN VARCHAR2, RECIPIENT IN VARCHAR2, SUBJECT IN VARCHAR2, MESSAGE IN VARCHAR2) IS
-- SENDER: direccion de correo de quien envia el mail
-- RECIPIENT: dirreción de correo a la que va dirigida el mail
-- SUBJECT: Es el asunto del correo
-- MESSAGE: es el texto del mensaje
mailhost CONSTANT VARCHAR2(30) := srv.mail.es; -- servidor de correo , sustituir cadena por una valida
mesg VARCHAR2(1000); -- texto del mensaje
mail_conn UTL_SMTP.CONNECTION; -- conexion con el servidor smtp
BEGIN
mail_conn := utl_smtp.open_connection(mailhost, 25);
mesg := 'Date: ' ||
TO_CHAR( SYSDATE, 'dd Mon yy hh24:mi:ss' ) || CHR(13) || CHR(10) ||
'From: <'|| Sender ||'>' || CHR(13) || CHR(10) ||
'Subject: '|| Subject || CHR(13) || CHR(10)||
'To: <'||Recipient || CHR(13) || CHR(10) || '>' || CHR(13) || CHR(10) || Message;
utl_smtp.helo(mail_conn, mailhost);
utl_smtp.mail(mail_conn, Sender);
utl_smtp.rcpt(mail_conn, Recipient);
utl_smtp.data(mail_conn, message);
utl_smtp.quit(mail_conn);
EXCEPTION
WHEN OTHERS THEN
RAISE_APPLICATION_ERROR(-20004,SQLERRM);
END send_mail;
/



La cadena del procedimiento que tras generar la alerta envia los parámetros al procedimiento SEND_MAIL es la siguiente:

send_mail('[email protected]','correo.desti [email protected]',
'ALERTA DE ESPACIO EN BASE DE DATOS ' || v_bbdd ,
'El tablespace ' || c_nombre || ' se esta quedando sin espacio' ||chr(10)||
'El espacio restante es de: ' || c_libre || ' Megas');


donde:
v_bbdd es el nombre de la base de datos
c_nombre es el nombre del tablespace
c_libre es el espacio que queda libre

El caso es que todo funciona correctamente a excepción de dos cosas:

cuando recibo el correo , en el para me aparece "undisclosed-recipient". No he indagado demasiado en el tema, pero presiento que es posible que esto tenga mas que ver con el servidor de correo, en cualquier caso no me es algo crítico.

Lo que si es problemático es que que "asunto" aparece en blanco. Es decir, da la sensación de que no está recibiendo el parámetro subject o si lo hace por algún motivo no lo está mostrando...

He pensado que el problema podria estar aqui:

utl_smtp.helo(mail_conn, mailhost);
utl_smtp.mail(mail_conn, Sender);
utl_smtp.rcpt(mail_conn, Recipient);
utl_smtp.data(mail_conn, message);
utl_smtp.quit(mail_conn);


Pero digo esto desde una total ignorancia, ya que mis conocimientos de PL/SQL son muy escasos, pero me mosquea que aqui aparezcan todos los parámetros excepto el subject

Un saludo
  #2 (permalink)  
Antiguo 24/06/2008, 10:00
Avatar de matanga  
Fecha de Ingreso: octubre-2007
Ubicación: España
Mensajes: 1.091
Antigüedad: 16 años, 4 meses
Puntos: 85
Respuesta: Procedimiento de envio de correo

Hola,

Te dejo un link donde ya comentamos sobre este paquete, hay varios ejemplos que son de utilidad.

http://www.forosdelweb.com/f100/ayud...l_smtp-555552/

Saludos
  #3 (permalink)  
Antiguo 25/06/2008, 09:32
 
Fecha de Ingreso: marzo-2005
Mensajes: 189
Antigüedad: 19 años
Puntos: 0
Respuesta: Procedimiento de envio de correo

Hola Matanga.
He revisado y rerevisado el post al que me has enviado, y lo cierto es que no se me ha servidor de mucho. Te explico:

He intentado instalar utl_mail pero resulta que no tengo el archivo utlmail.sql. Me parece que esta utilidad solo está en la 10g ¿me equivoco? Yo tengo 9i.

Entonces he intentado exprimir un poco la información que habia de utl_smtp, pero aunque si entiendo como funciona el script que estoy usando (o eso creo), no comprendo los que habeis puesto vosotros.
Sigo empeñado en que me debe faltar una linea que sea algo asi como:

utl_smtp.helo(mail_conn, mailhost);
utl_smtp.mail(mail_conn, Sender);
utl_smtp.rcpt(mail_conn, Recipient);
utl_smtp.data(mail_conn, message);
utl_smtp.asunto(mail_conn, subject); -> (es totalmente inventada...)
utl_smtp.quit(mail_conn);

Lo único en que me baso para pensar en que deberia ser así es porque sigo la pauta de los otros parámetros que sique funcionan.

Lo que me extraña es que este mismo script lo he encontrado exactamente igual en varios sitios de la red copiado letra por letra, por lo que debo pensar que muchos lo han usado y les ha funcionado bien, o bien que no les importa que no le aparezca el asunto.

¿alguien sabe como puedo hacer para que me aparezca el asunto en el correo que recibo usando este procedimiento?

¿debo buscarme otro trabajo tal como leñador por ejemplo?
  #4 (permalink)  
Antiguo 25/06/2008, 10:00
Avatar de matanga  
Fecha de Ingreso: octubre-2007
Ubicación: España
Mensajes: 1.091
Antigüedad: 16 años, 4 meses
Puntos: 85
Respuesta: Procedimiento de envio de correo

Hola,

Si te fijas en los dos ejemplos (el de jc3000 y el mio) sobre utl_smtp, veras que no existe el metodo utl_smtp.subject, simplemente porque no funciona asi.

ult_smtp es un package que abre un socket sobre el servidor de correo y negocia la conexion a bajo nivel, por eso hay que leerse la RFC que describe el formato de texto de un correo para saber como indicar dentro del buffer de datos cual es el subject.

A modo de resumen, te copio y pego parte de los ejemplos, el metodo utl_smtp.data es el que envia toda la informacion, incluyendo el asunto.

Código:
 
   --Header del mensaje - RFC 822
        sz_header :='Date: ' || TO_CHAR( SYSDATE, 'dd Mon yy hh24:mi:ss' ) || crlf ||
                    'From: '|| sz_from || crlf ||
                    'Subject: ' || sz_subject || crlf ||
                    'To: '  || sz_to_list_str || crlf ;

        sz_body := 'texto del mensaje';

        --Body del mensaje: lsz_body
        --Envío de datos al servidor de correo y cierre de la conexión
        r := UTL_SMTP.DATA(c, sz_header || lsz_body);
No tengo mucho mas para aportarte, el codigo que postee en su momento es el que tengo funcionando y el subject me aparece bien.

Saludos
  #5 (permalink)  
Antiguo 25/06/2008, 11:02
 
Fecha de Ingreso: enero-2008
Mensajes: 63
Antigüedad: 16 años, 1 mes
Puntos: 1
De acuerdo Respuesta: Procedimiento de envio de correo

Hola encontre un código en ZonaOracle.com y lo adecue a mis necesidades, esta muy bueno.

Código:
CREATE OR REPLACE procedure SIS.ejemplo3(
       phost            varchar2,   -- IP del servidor de correo
       premitente       varchar2,   -- Remitente
       pdestinatario    varchar2,   -- Destinatario
       pcc              varchar2,   -- Con copia
       pasunto          varchar2,   -- Asunto
       pcuerpo          varchar2)   -- Cuerpo del mensaje
-- Permite enviar un correo electrónico incluyendo un destinatario
is
       vconexion    utl_smtp.connection;
       
       -- Se construye la cabezera del mensaje
       function cabezera(
            vremitente     varchar2,
            vasunto        varchar2,
            vdestinatario  varchar2,
            vcc            varchar2)
       return varchar2
       is
            vcabezera   varchar2(32767);
       begin
            vcabezera := 'Return-Path: '||vremitente|| utl_tcp.crlf ||
                         'Sent: '||to_char(sysdate,'dd Mon yy hh24:mi:ss')|| utl_tcp.crlf ||
                         'From: '||vremitente|| utl_tcp.crlf ||
                         'Subject: '||vasunto|| utl_tcp.crlf ||
                         'To: '||vdestinatario|| utl_tcp.crlf ||
                         'Cc: '||vcc|| utl_tcp.crlf ||
                         'MIME-Version: 1.0'|| utl_tcp.crlf || -- use mime mail standard
                         'Content-Type: multipart/mixed; boundary="MIME.Bound"'|| utl_tcp.crlf || --mime.bound really should be a randomly generated string
                         'Content-Type: text/plain; charset=iso-8859-1'|| utl_tcp.crlf || 
                         'Content-Disposition: inline;' || utl_tcp.crlf ||
                         'Content-Transfer_Encoding: 8bit'|| utl_tcp.crlf;

            return vcabezera; 
       end;
       
       -- Se construye el cuerpo del mensaje
       function cuerpo(
            pbody       varchar2)
       return varchar2
       is
            vcadena     varchar2(10000);
            vposicion   number;
       begin
            -- Se procesa el mensaje, separandolo previamente de la cabezera con un crlf
            vcadena := pbody;
            vposicion := instr(vcadena,chr(10),1);
            while (vposicion<>0) loop
                    utl_smtp.write_data(vconexion, utl_tcp.crlf || substr(vcadena,1,vposicion-1));
                    vcadena   := ltrim(rtrim(substr(vcadena,vposicion+1)));
                    vposicion := instr(vcadena,chr(10),1);
            end loop;
            return vcadena;
       end;
              
begin
    -- Se establece la conexión al servidor de correo
    vconexion := utl_smtp.open_connection(phost);
        
    -- Se negocia la transacción con el servidor smtp
    utl_smtp.helo(vconexion, phost);
    utl_smtp.mail(vconexion, premitente);
    utl_smtp.rcpt(vconexion, pdestinatario);
    -- Si se envia copia a otro destinatario
    if ltrim(rtrim(pcc)) is not null then
        utl_smtp.rcpt(vconexion, pcc);
    end if;
        
    utl_smtp.open_data(vconexion);
    utl_smtp.write_data(vconexion, cabezera(premitente, pasunto, pdestinatario, pcc));
    
    -- Para permitir caracteres "raros" (tildes, simbolos, ...)
    utl_smtp.write_data(vconexion,'mime-version: 1.0' || utl_tcp.crlf);
    utl_smtp.write_data(vconexion,'content-type: text/plain; charset=iso-8859-1' || utl_tcp.crlf);

    -- Preparamos el cuerpo del correo
    utl_smtp.write_data(vconexion, utl_tcp.crlf || cuerpo(pcuerpo) || utl_tcp.crlf);
    utl_smtp.write_data(vconexion, utl_tcp.crlf);
      
    -- Cerramos la conexión
    utl_smtp.close_data(vconexion);
    utl_smtp.quit(vconexion);

exception
    when others then
        raise_application_error(sqlcode,sqlerrm,true);
        raise;
end ejemplo3;
/
Saludos
  #6 (permalink)  
Antiguo 26/06/2008, 01:17
 
Fecha de Ingreso: marzo-2005
Mensajes: 189
Antigüedad: 19 años
Puntos: 0
Respuesta: Procedimiento de envio de correo

¡Ya funciona!
Gracias Matanga, el último trozo de código que has puesto ha sido determinante para que mi dura mollera diese con la solución. aunque puede que también haya tenido algo de suerte....

Era tan dificili como sustituir esto utl_smtp.data(mail_conn, message); por esto otro utl_smtp.data(mail_conn, mesg);

En fin, gracias a todos por la ayuda y la paciencia.

Saludos
  #7 (permalink)  
Antiguo 26/06/2008, 01:23
 
Fecha de Ingreso: junio-2007
Mensajes: 891
Antigüedad: 16 años, 9 meses
Puntos: 43
Respuesta: Procedimiento de envio de correo

Esto es lo que utilizo yo en un proceso automatico que manda correos al finalizar un proceso con el resultado ( obviamente he quitado cosas "sercretas", je je je. Pero le he probado ahora mismo tal cual y me ha rulado :

PROCEDURE correo


IS


c utl_smtp.connection;

PROCEDURE send_header(name IN VARCHAR2, header IN VARCHAR2) AS
BEGIN
utl_smtp.write_data(c, name || ': ' || header || utl_tcp.CRLF);
END;

BEGIN




c := utl_smtp.open_connection('DIRECCION DEL SERVIDOR SMTP');
utl_smtp.helo(c, 'NOMBRE DEL SERVIDOR SMTP');
utl_smtp.mail(c, '[email protected]');-- Remitente


utl_smtp.rcpt(c, '[email protected]');--destinatario
utl_smtp.open_data(c);
send_header('Subject', 'Te pillé, golondrino');-- Asunto
--
-- A continuacion el texto del mensaje
--

utl_smtp.write_data(c, utl_tcp.CRLF || CHR(10)||'BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA ');--MENSAJE
utl_smtp.write_data(c, utl_tcp.CRLF || '================================================= ====== '||CHR(10)||CHR(10));--MENSAJE
--
-- FIN DE : A continuacion el texto del mensaje
--


utl_smtp.close_data(c);
utl_smtp.quit(c);

END CORREO ;
  #8 (permalink)  
Antiguo 08/08/2008, 14:31
 
Fecha de Ingreso: agosto-2008
Mensajes: 1
Antigüedad: 15 años, 7 meses
Puntos: 0
Respuesta: Procedimiento de envio de correo

Utilizo un procedure similar, para enviar mail; la consulta es que NO puedo enviar mails a varias destinatarios.

Gracias por adelantado.
  #9 (permalink)  
Antiguo 11/08/2008, 03:33
 
Fecha de Ingreso: junio-2007
Mensajes: 891
Antigüedad: 16 años, 9 meses
Puntos: 43
Respuesta: Procedimiento de envio de correo

Pues no es tan complicado, tio.

Haz un bucle y que dé tantas pasadas como destinatarios tenga ese correo.
  #10 (permalink)  
Antiguo 11/08/2008, 21:42
Avatar de kikolice  
Fecha de Ingreso: marzo-2004
Mensajes: 1.510
Antigüedad: 20 años
Puntos: 7
Respuesta: Procedimiento de envio de correo

independientemente de oracle, para enviar mails a varios destinatarios no es simplemente separarlos por "," (coma)??
__________________
Blogzote.com :-) Mi blog
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 08:04.