Saya menggunakan prosedur umum ini untuk mengirim surat. Ini juga mendukung lampiran (hanya teks biasa) dan email tidak dibatasi hingga 32767 karakter.
Jika Anda tidak memerlukan lampiran sama sekali, tidak masalah bagi Anda untuk menghapusnya.
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;
Sekedar catatan, jangan lewatkan UTL_SMTP.write_data(con, UTL_TCP.CRLF)
garis. Mereka terlihat berlebihan, namun kebanyakan dari mereka diperlukan! Juga pesan kehormatan seperti "Ini adalah pesan multibagian dalam format MIME." diperlukan untuk menampilkan email Anda dengan benar jika ada lampiran.
Jika Anda masih menghadapi masalah, buat dbms_output.put_line(ret.code||': '||ret.text);
setelah setiap panggilan fungsi pada UTL_SMTP.
Di sini prosedur yang sama tetapi dikurangi sesuai kebutuhan Anda:
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;