Oracle Send mail Implementation method _oracle

Source: Internet
Author: User
Tags base64 chr constant create directory exception handling server port
CREATE OR REPLACE PROCEDURE procsendemail (P_txt VARCHAR2,


P_sub VARCHAR2,


P_sendor VARCHAR2,


P_receiver VARCHAR2,


P_server VARCHAR2,


P_port number DEFAULT 25,


P_NEED_SMTP INT DEFAULT 0,


P_user VARCHAR2 DEFAULT NULL,


P_pass VARCHAR2 DEFAULT NULL,


P_filename VARCHAR2 DEFAULT NULL,


P_encode VARCHAR2 DEFAULT ' bit 7 ')


Authid Current_User is


/*


Role: Send mail with Oracle


Main function: 1, support multiple recipients.


2. Support Chinese


3, Support cc person


4. Support for attachments larger than 32K


5. Support multiple lines of text


6. Support Multiple Attachments


7, supporting text attachments and binary accessories


8. Support HTML format


8. Support


Author: Suk


Parameter description:


P_txt: Message body


P_SUB: Message headers


P_sendoraddress: Sender Email Address


P_receiveraddress: Receive address that can be sent to multiple addresses at the same time, between addresses with "," or ";" Separated


P_emailserver: Mail server address, can be a domain name or IP


P_port: Mail server port


P_NEED_SMTP: SMTP authentication required, 0 means not required, 1 means required


P_USER:SMTP Authentication Required User Name


P_PASS:SMTP Authentication Required Password


P_filename: The attachment name must contain the full path, such as "D:tempa.txt".


You can have multiple attachments, and the attachment names are separated by commas or semicolons.


P_encode: Attachment encoding conversion format, where p_encode= ' bit 7 ' indicates text type attachment


P_encode= ' base64 ' represents binary type attachments


Attention:


1, for the text type of attachment, can not be sent in base64 way, or error


2, for multiple attachments can only be sent in the same format


*/


L_crlf VARCHAR2 (2): = Utl_tcp. CRLF;


L_sendoraddress VARCHAR2 (4000);


L_splite VARCHAR2 (10): = ' + + ';


Boundary CONSTANT VARCHAR2 (256): = '-----Bysuk ';


First_boundary CONSTANT VARCHAR2 (256): = '--' | | Boundary | | L_crlf;


Last_boundary CONSTANT VARCHAR2 (256): = '--' | | Boundary | | '--' ||


L_crlf;


Multipart_mime_type CONSTANT VARCHAR2 (256): = ' multipart/mixed; boundary= "' | |


Boundary | | '"';


/* The following sections are used to send a sophomore into the attachment of the variable/


L_fil BFILE;


L_file_len number;


L_modulo number;


L_pieces number;


L_file_handle Utl_file. File_type;


L_amt Binary_integer: = 672 * 3;   /* ensures proper format; 2016 */


L_filepos Pls_integer: = 1; /* pointer for the file */


L_chunks number;


L_buf RAW (2100);


L_data RAW (2100);


L_max_line_width number: = 54;


L_directory_base_name VARCHAR2 (MB): = ' dir_for_send_mail ';


L_line VARCHAR2 (1000);


L_MESG VARCHAR2 (32767);


/* The above part is to send a sophomore into the accessories used in the variable * *


TYPE Address_list is TABLE of VARCHAR2 (m) INDEX by Binary_integer;


My_address_list address_list;


TYPE Acct_list is TABLE of VARCHAR2 (m) INDEX by Binary_integer;


My_acct_list acct_list;


-------------------------------------returns the directory or name of the attachment source file--------------------------------------


FUNCTION Get_file (P_file VARCHAR2,


P_get INT) return VARCHAR2 is


--p_get=1 represents the return directory


--p_get=2 Return file name


L_file VARCHAR2 (1000);


BEGIN


IF INSTR (P_file, ') > 0 THEN


--windows


IF p_get = 1 THEN


L_file: = SUBSTR (P_file, 1, INSTR (P_file, ',-1)-1);


elsif p_get = 2 THEN


L_file: = SUBSTR (P_file,-(LENGTH (P_file)-INSTR (P_file, ',-1)));


End IF;


Elsif INSTR (P_file, '/') > 0 THEN


--linux/unix


IF p_get = 1 THEN


L_file: = SUBSTR (P_file, 1, INSTR (p_file, '/',-1)-1);


elsif p_get = 2 THEN


L_file: = SUBSTR (P_file,-(LENGTH (P_file)-INSTR (P_file, '/',-1)));


End IF;


End IF;


return l_file;


End;


---------------------------------------------Delete directory------------------------------------


PROCEDURE drop_directory (P_directory_name VARCHAR2) is


BEGIN


EXECUTE IMMEDIATE ' Drop directory ' | | P_directory_name;


EXCEPTION


When others THEN


NULL;


End;


--------------------------------------------------Create directory-----------------------------------------


PROCEDURE create_directory (P_directory_name VARCHAR2,


P_dir VARCHAR2) is


BEGIN


EXECUTE IMMEDIATE ' Create directory ' | | P_directory_name | | ' as ' ' | |


P_dir | | '''';


EXECUTE IMMEDIATE ' Grant Read,write on directory ' | | P_directory_name | |


' to public ';


EXCEPTION


When others THEN


RAISE;


End;


--------------------------------------------split the e-mail address or the attachment address-----------------------------------


PROCEDURE p_splite_str (P_str VARCHAR2,


P_splite_flag INT DEFAULT 1) is


L_addr VARCHAR2 (254): = ';


L_len INT;


L_STR VARCHAR2 (4000);


J INT: = 0; --Represents the number of e-mail addresses or attachments


BEGIN


/* Processing receive mailing address list, including go to space, convert to, etc


L_STR: = TRIM (RTRIM (replace (p_str, '; ', ', ', ', ', ', '), ', '));


L_len: = LENGTH (L_STR);


For I in 1. L_len LOOP


IF SUBSTR (L_str, I, 1) <> ', ' THEN


L_ADDR: = L_addr | | SUBSTR (L_str, I, 1);


ELSE


J: = j + 1;


IF P_splite_flag = 1 THEN--Represents processing mail address


--before and after need to add ' <> ', otherwise many mailboxes will not be able to send mail


L_ADDR: = ' < ' | | l_addr | | ' > ';


--Invoke mail send process


My_address_list (J): = L_ADDR;


elsif P_splite_flag = 2 THEN--Representing processing attachment name


My_acct_list (J): = L_ADDR;


End IF;


L_ADDR: = ';


End IF;


IF I = L_len THEN


J: = j + 1;


IF P_splite_flag = 1 THEN


--Invoke mail send process


L_ADDR: = ' < ' | | l_addr | | ' > ';


My_address_list (J): = L_ADDR;


elsif P_splite_flag = 2 THEN


My_acct_list (J): = L_ADDR;


End IF;


End IF;


End LOOP;


End;


------------------------------------------------write headers and message content------------------------------------------


PROCEDURE Write_data (P_conn in Out Nocopy utl_smtp. CONNECTION,


P_name in VARCHAR2,


P_value in VARCHAR2,


P_splite VARCHAR2 DEFAULT ': ',


P_crlf VARCHAR2 DEFAULT L_crlf) is


BEGIN


/* Utl_raw.cast_to_raw is very important to solve the problem of garbled Chinese * *


Utl_smtp. Write_raw_data (P_conn, Utl_raw. Cast_to_raw (CONVERT (P_name | |


P_splite | |


P_value | |


P_crlf, ' ZHS16GBK '));


End;


----------------------------------------write MIME message tail-----------------------------------------------------


PROCEDUREEnd_boundary(CONN in Out Nocopy utl_smtp.) CONNECTION,


Last in BOOLEAN DEFAULT FALSE) is


BEGIN


Utl_smtp. Write_data (CONN, utl_tcp. CRLF);


IF (last) THEN


Utl_smtp. Write_data (CONN, last_boundary);


End IF;


End;


----------------------------------------------Send an attachment----------------------------------------------------


PROCEDURE attachment (CONN in Out Nocopy utl_smtp. CONNECTION,


Mime_type in VARCHAR2 DEFAULT ' Text/plain ',


INLINE in BOOLEAN DEFAULT TRUE,


FILENAME in VARCHAR2 DEFAULT ' T.txt ',


Transfer_enc in VARCHAR2 DEFAULT ' 7 bit ',


Dt_name in VARCHAR2 DEFAULT ' 0 ') is





L_filename VARCHAR2 (1000);


BEGIN


--Write Attachment head


Utl_smtp. Write_data (CONN, first_boundary);


--Formatting attachments


Write_data (CONN, ' Content-type ', mime_type);


--If the file name is not empty, the attachment is indicated


Drop_directory (Dt_name);


--Create Directory


Create_directory (Dt_name, Get_file (FILENAME, 1));


--Get the name of the attachment file


L_filename: = Get_file (FILENAME, 2);


IF (INLINE) THEN


Write_data (CONN, ' content-disposition ', ' inline; filename= ') ' | |


L_filename | | '"');


ELSE


Write_data (CONN, ' content-disposition ', ' attachment; filename= ') ' | |


L_filename | | '"');


End IF;


--Set the conversion format for the attachment


IF (Transfer_enc is not NULL) THEN


Write_data (CONN, ' content-transfer-encoding ', transfer_enc);


End IF;





Utl_smtp. Write_data (CONN, utl_tcp. CRLF);





--begin attached content


IF Transfer_enc = ' bit 7 ' THEN


--If the attachment is a text type


BEGIN


L_file_handle: = Utl_file. FOPEN (Dt_name, L_filename, ' R '); --Open File


--Divide the attachment into multiple parts so that you can send more than 32K of accessories


LOOP


Utl_file. Get_line (L_file_handle, l_line);


L_MESG: = L_line | | L_crlf;


Write_data (CONN, ', L_MESG, ', ');


End LOOP;


Utl_file. FCLOSE (L_file_handle);


End_boundary(CONN);


EXCEPTION


When others THEN


Utl_file. FCLOSE (L_file_handle);


End_boundary(CONN);


NULL;


End; --Ending processing of text type attachments





elsif transfer_enc = ' base64 ' THEN


--If the binary type is an attachment


BEGIN


--Divide the attachment into multiple parts so that you can send more than 32K of accessories


L_filepos: = 1;--Reset offset, must reset when multiple attachments are sent


L_fil: = Bfilename (Dt_name, l_filename);


L_file_len: = Dbms_lob. GetLength (L_fil);


L_modulo: = MOD (L_file_len, L_amt);


L_pieces: = TRUNC (L_file_len/l_amt);


IF (l_modulo <> 0) THEN


L_pieces: = l_pieces + 1;


End IF;


Dbms_lob. FILEOPEN (L_fil, Dbms_lob. FILE_READONLY);


Dbms_lob. READ (L_fil, L_amt, L_filepos, l_buf);


L_data: = NULL;


For I in 1. L_pieces LOOP


L_filepos: = I * L_amt + 1;


L_file_len: = L_file_len-l_amt;


L_data: = Utl_raw. CONCAT (L_data, l_buf);


L_chunks: = TRUNC (Utl_raw. LENGTH (l_data)/l_max_line_width);


IF (I <> l_pieces) THEN


L_chunks: = l_chunks-1;


End IF;


Utl_smtp. Write_raw_data (CONN, Utl_encode. Base64_encode (L_data));


L_data: = NULL;


IF (L_file_len < L_amt and L_file_len > 0) THEN


L_amt: = L_file_len;


End IF;


Dbms_lob. READ (L_fil, L_amt, L_filepos, l_buf);


End LOOP;


Dbms_lob. FileClose (L_fil);


End_boundary(CONN);


EXCEPTION


When others THEN


Dbms_lob. FileClose (L_fil);


End_boundary(CONN);


RAISE;


End; --end processing of binary attachments





End IF; --End processing attachment content


Drop_directory (Dt_name);


End; --End Process attachment


---------------------------------------------the process of actually sending a message--------------------------------------------


PROCEDURE P_email (P_sendoraddress2 VARCHAR2,--Send address


P_receiveraddress2 VARCHAR2)--Accept Address


Is


L_conn UTL_SMTP. CONNECTION; --Defining connections


BEGIN


/* Initialize mail server information, connect to mail server * *


L_conn: = Utl_smtp. Open_connection (P_server, P_port);


Utl_smtp. HELO (L_conn, p_server);


/* SMTP Server login Check/*


IF P_NEED_SMTP = 1 THEN


Utl_smtp.command (L_conn, ' AUTH LOGIN ', ');


Utl_smtp.command (L_conn, Utl_raw. Cast_to_varchar2 (Utl_encode. Base64_encode (Utl_raw. Cast_to_raw (P_user)));


Utl_smtp.command (L_conn, Utl_raw. Cast_to_varchar2 (Utl_encode. Base64_encode (Utl_raw. Cast_to_raw (P_pass)));


End IF;





/* Set send address and receive address * *


Utl_smtp. MAIL (L_conn, P_SENDORADDRESS2);


Utl_smtp. RCPT (L_conn, P_RECEIVERADDRESS2);





/* Set the message header * *


Utl_smtp. Open_data (L_conn);





Write_data (L_conn, ' Date ', To_char (sysdate, ' Yyyy-mm-dd hh24:mi:ss '));


/* Set Send person/*


Write_data (L_conn, ' from ', P_sendor);


/* Set receiver/*.


Write_data (L_conn, ' to ', p_receiver);


/* Set the message Theme * *


Write_data (L_conn, ' Subject ', p_sub);





Write_data (L_conn, ' Content-type ', multipart_mime_type);


Utl_smtp. Write_data (L_conn, utl_tcp. CRLF);


Utl_smtp. Write_data (L_conn, first_boundary);


Write_data (L_conn, ' content-type ', ' text/plain;charset=gb2312 ');


--Blank line alone, otherwise, body content does not appear


Utl_smtp. Write_data (L_conn, utl_tcp. CRLF);


/* Set message body


Restore the Separator to Chr (10). This is primarily to invoke the procedure in the shell, and if there are more than one line, the contents of the multiple rows are merged into a single line.
Separated by L_splite and replaced with L_crlf Chr (10). This step is necessary, otherwise you will not be able to send messages with multiple lines in the body of the message

*/
Write_data (L_conn, ', replace (P_txt, L_splite, CHR), CHR (a), L_crlf), ', ';
End_boundary (L_conn);

--Send an attachment if the file name is not empty
IF (P_filename is not NULL) THEN
--Split attachment address by comma or semicolon
P_splite_str (P_filename, 2);
--Loops send attachments (in same message)
For K in 1. My_acct_list. COUNT LOOP
P_encode, dt_name => l_directory_base_name | |


To_char (K));


End LOOP;


End IF;





/* Close Data Write/*


Utl_smtp. Close_data (L_conn);


/* Close Connection * *


Utl_smtp. QUIT (L_conn);





/* Exception Handling * *


EXCEPTION


When others THEN


NULL;


RAISE;





End;


---------------------------------------------------the main process-----------------------------------------------------


BEGIN


L_sendoraddress: = ' < ' | | P_sendor | | ' > ';


P_splite_str (P_receiver);--Processing mail addresses


For K in 1. My_address_list. COUNT LOOP


P_email (L_sendoraddress, My_address_list (K));


End LOOP;


/* Process email address, split message according to Comma * *


EXCEPTION


When others THEN


RAISE;


End;


 
  usages: 
    
   

  code:  
 
            


SQL set serverout on


SQL > exec procsendemail ( ' Chinese test mail ' , ' Chinese theme ' , ' space6212@163.com ' , ' space6212@163.com
    , susk@souchang.com ' ,  ' 202.108.5.85 ' ,  ,  1 ,  ' xxxx ' ,  ' XXXX ' ,  '/tmp/a.jpg,/tmp/b.jpg ' ,  ' base64 ' ; 


PL / SQL procedure successfully completed

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.