Използвам тази обща процедура за изпращане на имейли. Той също така поддържа прикачени файлове (само обикновен текст) и имейлите не са ограничени до 32767 знака.
Ако изобщо не се нуждаете от прикачени файлове, не би трябвало да е проблем да ги премахнете.
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;
Само забележка, не пропускайте UTL_SMTP.write_data(con, UTL_TCP.CRLF)
линии. Те изглеждат излишни, но повечето от тях са необходими! Също така любезно съобщение като „Това е съобщение от няколко части във формат MIME“. е необходим за правилното показване на вашата поща в случай на прикачени файлове.
Ако все още имате проблеми, направете dbms_output.put_line(ret.code||': '||ret.text);
след всяко извикване на функция на UTL_SMTP.
Ето същата процедура, но съобразена с вашите нужди:
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;