Reputation: 233
I have a .txt file in which I have stored my data Semicolon-separated.
The file is stored at backend in a Clob
.
File:
ABCD;HEAD; 1.0;00204;18.05.2015;00000000;00000000000.00;18.05.2015
I need to send this text file as an attachment via Stored Procedure in Oracle.
Problem:
I get this encoded file attached in the Email:
4546554C3B484541443B20202020202020312E303B30303634323B31382E30352E323031353B30303030303030313B30303030303030303032302E30303B31382E30352E323031350A4546554C3B444154413B20202020202020312E303B4546554C3B303030543130303030303335303B313B31382E30352E323031353B303030303032302C3030302E30303B504B523B3132363435363135313231313B303235303533313030310D0A
Procedure:
CREATE OR REPLACE PROCEDURE SENDMAIL_ATT
(
MSG_FROM VARCHAR2,
MSG_TO VARCHAR2,
MSG_SUBJECT VARCHAR2,
MSG_TEXT VARCHAR2,
MSG_ATT CLOB,
ATT_FILENAME VARCHAR2
) IS
V_MAILHOST VARCHAR2(50) := 'mail_server';
V_PORT NUMBER(2) := 25;
V_HELO VARCHAR2(50) := 'localhost';
C UTL_TCP.CONNECTION;
RC INTEGER;
CRLF VARCHAR2(2) := CHR(13) || CHR(10);
MESG VARCHAR2(32767);
V_BUFFER_SIZE CONSTANT PLS_INTEGER := 4000;
V_BUFFER_NEXT PLS_INTEGER := 4000;
V_BODY_BUFFER VARCHAR2(8000 CHAR);
BEGIN
C := UTL_TCP.OPEN_CONNECTION(V_MAILHOST, V_PORT); -- open the SMTP port
DBMS_OUTPUT.PUT_LINE(UTL_TCP.GET_LINE(C, TRUE));
RC := UTL_TCP.WRITE_LINE(C, 'HELO ' || V_HELO);
DBMS_OUTPUT.PUT_LINE(UTL_TCP.GET_LINE(C, TRUE));
RC := UTL_TCP.WRITE_LINE(C, 'MAIL FROM: ' || MSG_FROM); ----- MAIL BOX SENDING THE EMAIL
DBMS_OUTPUT.PUT_LINE(UTL_TCP.GET_LINE(C, TRUE));
RC := UTL_TCP.WRITE_LINE(C, 'RCPT TO: ' || MSG_TO); ----- MAIL BOX RECIEVING THE EMAIL
DBMS_OUTPUT.PUT_LINE(UTL_TCP.GET_LINE(C, TRUE));
RC := UTL_TCP.WRITE_LINE(C, 'DATA'); ----- EMAIL MESSAGE BODY START
DBMS_OUTPUT.PUT_LINE(UTL_TCP.GET_LINE(C, TRUE));
RC := UTL_TCP.WRITE_LINE(C,'Date: ' ||
TO_CHAR(SYSDATE, 'dd Mon yy hh24:mi:ss'));
RC := UTL_TCP.WRITE_LINE(C, 'From: ' || MSG_FROM);
RC := UTL_TCP.WRITE_LINE(C, 'MIME-Version: 1.0');
RC := UTL_TCP.WRITE_LINE(C, 'To: ' || MSG_TO);
RC := UTL_TCP.WRITE_LINE(C, 'Subject: ' || MSG_SUBJECT);
RC := UTL_TCP.WRITE_LINE(C, 'Content-Type: multipart/mixed;'); ----- INDICATES THAT THE BODY CONSISTS OF MORE THAN ONE PART
RC := UTL_TCP.WRITE_LINE(C, ' boundary="-----SECBOUND"'); ----- SEPERATOR USED TO SEPERATE THE BODY PARTS
RC := UTL_TCP.WRITE_LINE(C); ----- DO NOT REMOVE THIS BLANK LINE - PART OF MIME STANDARD
RC := UTL_TCP.WRITE_LINE(C, '-------SECBOUND');
RC := UTL_TCP.WRITE_LINE(C, 'Content-Type: text/html'); ----- 1ST BODY PART. EMAIL TEXT MESSAGE
RC := UTL_TCP.WRITE_LINE(C, 'Content-Transfer-Encoding: 7bit');
RC := UTL_TCP.WRITE_LINE(C);
RC := UTL_TCP.WRITE_LINE(C, MSG_TEXT); ----- TEXT OF EMAIL MESSAGE
RC := UTL_TCP.WRITE_LINE(C);
RC := UTL_TCP.WRITE_LINE(C, '-------SECBOUND');
RC := UTL_TCP.WRITE_LINE(C, 'Content-Type: text/plain;'); ----- 2ND BODY PART.
RC := UTL_TCP.WRITE_LINE(C, ' name="' || ATT_FILENAME || '"');
RC := UTL_TCP.WRITE_LINE(C, 'Content-Transfer_Encoding: 7bit');
RC := UTL_TCP.WRITE_LINE(C, 'Content-Disposition: attachment;'); ----- INDICATES THAT THIS IS AN ATTACHMENT
RC := UTL_TCP.WRITE_LINE(C, ' filename="' || ATT_FILENAME || '"'); ----- SUGGESTED FILE NAME FOR ATTACHMENT
RC := UTL_TCP.WRITE_LINE(C);
--CLOB
FOR I IN 0 .. FLOOR(DBMS_LOB.GETLENGTH(MSG_ATT) / V_BUFFER_SIZE)
LOOP
DBMS_LOB.READ(MSG_ATT,
V_BUFFER_NEXT,
I * V_BUFFER_SIZE + 1,
V_BODY_BUFFER);
RC := UTL_TCP.WRITE_TEXT(C, V_BODY_BUFFER);
END LOOP;
RC := UTL_TCP.WRITE_LINE(C);
RC := UTL_TCP.WRITE_LINE(C, '.'); ----- EMAIL MESSAGE BODY END
DBMS_OUTPUT.PUT_LINE(UTL_TCP.GET_LINE(C, TRUE));
RC := UTL_TCP.WRITE_LINE(C, 'QUIT'); ----- ENDS EMAIL TRANSACTION
DBMS_OUTPUT.PUT_LINE(UTL_TCP.GET_LINE(C, TRUE));
UTL_TCP.CLOSE_CONNECTION(C); ----- CLOSE SMTP PORT CONNECTION
EXCEPTION
WHEN OTHERS THEN
RAISE;
END SENDMAIL_ATT;
Procedure Call:
declare
-- Local variables here
l_clob clob;
fileName varchar2(100);
begin
SELECT file_name, file_content
INTO fileName, l_clob
FROM my_table
WHERE ID = 141;
SENDMAIL_ATT(MSG_FROM => '[email protected]',
MSG_TO => '[email protected]',
MSG_SUBJECT => 'Test Email',
MSG_TEXT => 'Some Subject',
MSG_ATT => l_clob,
ATT_FILENAME => fileName);
end;
Upvotes: 0
Views: 4152
Reputation: 59436
I use this package to send out mails. It works fine with attachments, try it out:
CREATE OR REPLACE PACKAGE BODY SENDMAIL_PKG AS
PRIORITY_HIGH CONSTANT INTEGER := 1;
PRIORITY_NORMAL CONSTANT INTEGER := 3;
PRIORITY_LOW CONSTANT INTEGER := 5;
SMTP_PORT CONSTANT INTEGER := 25;
SMTP_SERVER CONSTANT VARCHAR2(50) := 'mailhost';
SMTP_DOMIAN CONSTANT VARCHAR2(50) := SYS_CONTEXT('USERENV', 'DB_DOMAIN');
MIME_BOUNDARY CONSTANT VARCHAR2(50) := '=====Boundary======';
MIME_MIXED CONSTANT VARCHAR2(50) := 'multipart/mixed;';
MIME_TEXT CONSTANT VARCHAR2(50) := 'text/plain;';
DEFAULT_FROM_NAME CONSTANT VARCHAR2(50) := SYS_CONTEXT('USERENV', 'CURRENT_SCHEMA');
DEFAULT_FROM_MAIL CONSTANT VARCHAR2(50) := DEFAULT_FROM_NAME||'@'||SMTP_DOMIAN;
FUNCTION OpenConnection(ToEmail IN VARCHAR2, FromEmail IN VARCHAR2) RETURN UTL_SMTP.connection IS
con UTL_SMTP.connection;
BEGIN
-- setup mail header
con := UTL_SMTP.OPEN_CONNECTION(SMTP_SERVER, SMTP_PORT);
UTL_SMTP.helo(con, SMTP_DOMIAN);
UTL_SMTP.Mail(con, LOWER(FromEmail));
UTL_SMTP.rcpt(con, LOWER(ToEmail));
UTL_SMTP.open_data(con);
RETURN con;
END OpenConnection;
PROCEDURE PutHeader(con IN OUT UTL_SMTP.connection,
Subject IN VARCHAR2, ToEmail IN VARCHAR2,
FromEmail IN VARCHAR2, FromName IN VARCHAR2,
Priority IN INTEGER) IS
BEGIN
UTL_SMTP.write_data(con, 'From: "'||FromName||'" <'||LOWER(FromEmail)||'>'||UTL_TCP.CRLF);
UTL_SMTP.write_data(con, 'To: <'||LOWER(ToEmail)||'>'||UTL_TCP.CRLF);
UTL_SMTP.write_data(con, 'Subject: '||Subject||UTL_TCP.CRLF);
UTL_SMTP.write_data(con, 'X-Priority: '||Priority||UTL_TCP.CRLF);
END PutHeader;
PROCEDURE CloseMail(con IN OUT UTL_SMTP.connection) IS
BEGIN
-- finish mail
UTL_SMTP.close_data(con);
UTL_SMTP.quit(con);
END CloseMail;
-- Append default footer at the end of mail
PROCEDURE PutFooter(con IN OUT UTL_SMTP.connection) IS
sender VARCHAR2(1000);
BEGIN
-- put footer to end of mail
UTL_SMTP.write_data(con, UTL_TCP.CRLF || UTL_TCP.CRLF);
sender := SYS_CONTEXT('USERENV', 'DB_NAME')||'.'||SYS_CONTEXT('USERENV', 'DB_DOMAIN');
UTL_SMTP.write_data(con, 'Message from '||sender||' sent at '||TO_CHAR(LOCALTIMESTAMP, 'yyyy-mm-dd hh24:mi:ss'));
UTL_SMTP.write_data(con, UTL_TCP.CRLF);
END PutFooter;
-- Send Mail with CLOB attachment
PROCEDURE SendMail(
Subject IN VARCHAR2,
Message IN VARCHAR2,
ToEmail IN VARCHAR2,
Attachment IN CLOB, FilenameAttachment IN VARCHAR2,
FromEmail IN VARCHAR2 DEFAULT DEFAULT_FROM_MAIL,
FromName IN VARCHAR2 DEFAULT DEFAULT_FROM_NAME,
Priority IN INTEGER DEFAULT PRIORITY_NORMAL) IS
con UTL_SMTP.connection;
AttachmentLength PLS_INTEGER;
amount BINARY_INTEGER := 30000;
BUFFER VARCHAR2(32000);
offset PLS_INTEGER := 1;
BEGIN
con := OpenConnection(ToEmail, FromEmail);
PutHeader(con, Subject, ToEmail, FromEmail, FromName, Priority);
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, '--'||MIME_BOUNDARY || UTL_TCP.CRLF);
UTL_SMTP.write_data(con, 'Content-type: text/plain' || UTL_TCP.CRLF);
-- 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);
PutFooter(con);
-- 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="'||FilenameAttachment||'"'|| UTL_TCP.CRLF);
UTL_SMTP.write_data(con, 'Content-Disposition: attachment; filename="'||FilenameAttachment||'"'|| UTL_TCP.CRLF);
UTL_SMTP.write_data(con, UTL_TCP.CRLF);
AttachmentLength := DBMS_LOB.GETLENGTH(Attachment);
LOOP
EXIT WHEN offset > AttachmentLength;
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);
CloseMail(con);
END SendMail;
-- Send plain Mail without attachment
PROCEDURE SendMail(
Subject IN VARCHAR2,
Message IN VARCHAR2,
ToEmail IN VARCHAR2,
FromEmail IN VARCHAR2 DEFAULT DEFAULT_FROM_MAIL,
FromName IN VARCHAR2 DEFAULT DEFAULT_FROM_NAME,
Priority IN INTEGER DEFAULT PRIORITY_NORMAL) IS
con UTL_SMTP.connection;
BEGIN
con := OpenConnection(ToEmail, FromEmail);
PutHeader(con, Subject, ToEmail, FromEmail, FromName, Priority);
UTL_SMTP.write_data(con, 'Content-type: '||MIME_TEXT ||' charset='||GetCharset||UTL_TCP.CRLF );
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);
PutFooter(con);
CloseMail(con);
END SendMail;
END SENDMAIL_PKG;
Upvotes: 2