Oracle
 sql >> Base de données >  >> RDS >> Oracle

Comment envoyer un e-mail à l'aide d'Oracle 10 g Forms

J'utilise cette procédure générale pour envoyer des mails. Il prend également en charge les pièces jointes (texte brut uniquement) et les e-mails ne sont pas limités à 32767 caractères.

Si vous n'avez pas du tout besoin de pièces jointes, cela ne devrait pas vous poser de problème de les supprimer.

PRIORITY_HIGH           CONSTANT INTEGER := 1;
PRIORITY_NORMAL         CONSTANT INTEGER := 3;
PRIORITY_LOW            CONSTANT INTEGER := 5;


PROCEDURE SendMail(
    Subject IN VARCHAR2, 
    Message IN OUT CLOB, 
    ToMail IN VARCHAR2,   
    FromMail IN VARCHAR2, FromName IN VARCHAR2,
    Attachment IN OUT CLOB, FileName IN VARCHAR2,
    Priority IN INTEGER DEFAULT PRIORITY_NORMAL) IS

    MIME_BOUNDARY   CONSTANT VARCHAR2(50) := '====Multipart.Boundary.689464861147414354====';
    MIME_MIXED      CONSTANT VARCHAR2(50) := 'multipart/mixed;';
    MIME_TEXT       CONSTANT VARCHAR2(50) := 'text/plain;';
    MIME_HTML       CONSTANT VARCHAR2(50) := 'text/html;';  
    MAIL_HOST       CONSTANT VARCHAR2(50) := '192.168.0.6'; -- try also 'mailhost'

    con UTL_SMTP.connection;
    ret UTL_SMTP.reply;
    Charset VARCHAR2(20);
    Footer VARCHAR2(1000);

    ClobLen PLS_INTEGER;
    amount BINARY_INTEGER := 8192;
    buffer VARCHAR2(16384);
    offset PLS_INTEGER := 1;
    isHTML BOOLEAN := REGEXP_LIKE(DBMS_LOB.SUBSTR(Message, 1000, 1), '<(html)|(body)', 'i');

BEGIN

    SELECT UTL_I18N.MAP_CHARSET(VALUE)
    INTO Charset
    FROM V$NLS_PARAMETERS
    WHERE PARAMETER = 'NLS_CHARACTERSET';

    -- setup mail header
    con := UTL_SMTP.OPEN_CONNECTION(MAIL_HOST, 25);
    ret := UTL_SMTP.helo(con, SYS_CONTEXT('USERENV', 'DB_DOMAIN')); -- assuming your database is in the same domain as your mail server
    ret := UTL_SMTP.Mail(con, FromMail);
    ret := UTL_SMTP.rcpt(con, ToMail);
    -- simply call "UTL_SMTP.rcpt(con, ...);" again in order to add further recipient
    ret := UTL_SMTP.open_data(con);

    IF FromName IS NOT NULL THEN
        UTL_SMTP.write_data(con, 'From: "'||FromName||'" <'||FromMail||'>'||Utl_Tcp.CRLF);
    ELSE
        UTL_SMTP.write_data(con, 'From: <'||FromMail||'>'||Utl_Tcp.CRLF);
    END IF;
    UTL_SMTP.write_data(con, 'To: <'||ToMail||'>'||Utl_Tcp.CRLF);
    --  UTL_SMTP.write_data(con, 'Cc: <'||CcMail||'>'||Utl_Tcp.CRLF);       
    UTL_SMTP.write_data(con, 'Subject: '||Subject||Utl_Tcp.CRLF);
    UTL_SMTP.write_data(con, 'X-Priority: '||Priority||Utl_Tcp.CRLF);

    IF Attachment IS NOT NULL AND FileName IS NOT NULL THEN
        UTL_SMTP.write_data(con, 'Mime-Version: 1.0' || Utl_Tcp.CRLF);
        UTL_SMTP.write_data(con, 'Content-Type: '||MIME_MIXED||' boundary="'||MIME_BOUNDARY||'"' || Utl_Tcp.CRLF);
        UTL_SMTP.write_data(con, 'This is a multipart message in MIME format.' || Utl_Tcp.CRLF);
        UTL_SMTP.write_data(con, '--'||MIME_BOUNDARY || Utl_Tcp.CRLF);
    END IF;

    Footer := 'Message from '||SYS_CONTEXT('USERENV', 'DB_NAME')||' sent at '||TO_CHAR(SYSDATE,'yyyy-mm-dd hh24:mi:ss');
    IF isHTML THEN
        UTL_SMTP.write_data(con, 'Content-type: '||MIME_HTML||' charset='||Charset || Utl_Tcp.CRLF);
        Message := REPLACE(message, '</body>', '<p>'||Footer||'</p></body>');
    ELSE 
        UTL_SMTP.write_data(con, 'Content-type: '||MIME_TEXT||' charset='||Charset || Utl_Tcp.CRLF);
    END IF;

    -- Mail Body
    UTL_SMTP.write_data(con, Utl_Tcp.CRLF);
    ClobLen := DBMS_LOB.GETLENGTH(Message);
    LOOP
        EXIT WHEN offset > ClobLen;
        DBMS_LOB.READ(Message, amount, offset, BUFFER);
        UTL_SMTP.write_raw_data(con, UTL_RAW.cast_to_raw(BUFFER));
        offset := offset + amount;
    END LOOP;   
    UTL_SMTP.write_data(con, Utl_Tcp.CRLF);
    IF NOT isHTML THEN
        UTL_SMTP.write_data(con, Utl_Tcp.CRLF || Utl_Tcp.CRLF);
        UTL_SMTP.write_data(con, Footer);
        UTL_SMTP.write_data(con, Utl_Tcp.CRLF);
    END IF;

    IF Attachment IS NOT NULL AND FileName IS NOT NULL THEN
        -- Mail Attachment
        UTL_SMTP.write_data(con, Utl_Tcp.CRLF);
        UTL_SMTP.write_data(con, '--'||MIME_BOUNDARY || Utl_Tcp.CRLF);
        UTL_SMTP.write_data(con, 'Content-Type: '||MIME_TEXT||' name="'||Filename||'"'|| Utl_Tcp.CRLF);
        UTL_SMTP.write_data(con, 'Content-Disposition: attachment; filename="'||Filename||'"'|| Utl_Tcp.CRLF);
        UTL_SMTP.write_data(con, Utl_Tcp.CRLF);

        offset := 1;
        ClobLen := DBMS_LOB.GETLENGTH(Attachment);
        LOOP
            EXIT WHEN offset > ClobLen;
            DBMS_LOB.READ(Attachment, amount, offset, BUFFER);
            UTL_SMTP.write_raw_data(con, Utl_Raw.cast_to_raw(BUFFER));
            offset := offset + amount;
        END LOOP;
        UTL_SMTP.write_data(con, Utl_Tcp.CRLF);
        UTL_SMTP.write_data(con, '--'||MIME_BOUNDARY||'--' || Utl_Tcp.CRLF);
    END IF;

    -- finish mail
    ret := UTL_SMTP.close_data(con);
    ret := UTL_SMTP.quit(con);

EXCEPTION
    WHEN UTL_SMTP.TRANSIENT_ERROR OR UTL_SMTP.PERMANENT_ERROR THEN
        UTL_SMTP.quit(con);
        RAISE;
END SendMail;

Juste une note, ne manquez pas le UTL_SMTP.write_data(con, UTL_TCP.CRLF) lignes. Ils semblent redondants, mais la plupart d'entre eux sont nécessaires ! Également un message de courtoisie comme "Ceci est un message en plusieurs parties au format MIME." est nécessaire pour un bon affichage de votre courrier en cas de pièces jointes.

Si vous rencontrez toujours des problèmes, faites un dbms_output.put_line(ret.code||': '||ret.text); après chaque appel de fonction sur UTL_SMTP.

Ici la même procédure mais réduite à vos besoins :

FUNCTION SendMail(
    Subject IN VARCHAR2, 
    Message IN VARCHAR2, 
    FromMail IN VARCHAR2, FromName IN VARCHAR2, 
    ToMail IN VARCHAR2) RETURN VARCHAR2 IS

    MIME_TEXT       CONSTANT VARCHAR2(50) := 'text/plain;';
    MIME_HTML       CONSTANT VARCHAR2(50) := 'text/html;';  
    MAIL_HOST       CONSTANT VARCHAR2(50) := '192.168.0.6'; -- try also 'mailhost'

    con UTL_SMTP.connection;
    ret UTL_SMTP.reply;
    Charset VARCHAR2(20);
    isHTML BOOLEAN := REGEXP_LIKE(DBMS_LOB.SUBSTR(Message, 1000, 1), '<(html)|(body)', 'i');

BEGIN

    SELECT UTL_I18N.MAP_CHARSET(VALUE)
    INTO Charset
    FROM V$NLS_PARAMETERS
    WHERE PARAMETER = 'NLS_CHARACTERSET';

    -- setup mail header
    con := UTL_SMTP.OPEN_CONNECTION(MAIL_HOST, 25);
    ret := UTL_SMTP.helo(con, SYS_CONTEXT('USERENV', 'DB_DOMAIN')); -- assuming your database is in the same domain as your mail server
    ret := UTL_SMTP.Mail(con, FromMail);
    ret := UTL_SMTP.rcpt(con, ToMail);
    ret := UTL_SMTP.open_data(con);

    UTL_SMTP.write_data(con, 'From: "'||FromName||'" <'||FromMail||'>'||Utl_Tcp.CRLF);
    UTL_SMTP.write_data(con, 'To: <'||ToMail||'>'||Utl_Tcp.CRLF);
    UTL_SMTP.write_data(con, 'Subject: '||Subject||Utl_Tcp.CRLF);
    UTL_SMTP.write_data(con, 'X-Priority: 3'||Utl_Tcp.CRLF);

    IF isHTML THEN
        UTL_SMTP.write_data(con, 'Content-type: '||MIME_HTML||' charset='||Charset || Utl_Tcp.CRLF);
    ELSE 
        UTL_SMTP.write_data(con, 'Content-type: '||MIME_TEXT||' charset='||Charset || Utl_Tcp.CRLF);
    END IF;

    -- Mail Body
    UTL_SMTP.write_data(con, Utl_Tcp.CRLF);
    UTL_SMTP.write_raw_data(con, UTL_RAW.cast_to_raw(Message));
    UTL_SMTP.write_data(con, Utl_Tcp.CRLF);

    -- finish mail
    ret := UTL_SMTP.close_data(con);
    ret := UTL_SMTP.quit(con);
    RETURN '0';    
EXCEPTION
    WHEN UTL_SMTP.TRANSIENT_ERROR OR UTL_SMTP.PERMANENT_ERROR THEN
        UTL_SMTP.quit(con);
        RETURN SQLERRM;
END SendMail;