oracle发送邮件编码.docx
《oracle发送邮件编码.docx》由会员分享,可在线阅读,更多相关《oracle发送邮件编码.docx(21页珍藏版)》请在冰豆网上搜索。
oracle发送邮件编码
主要功能:
1、支持多收件人。
2、支持中文
3、支持大于32K的附件
4、支持多行正文
5、支持多附件
6、支持文本附件和二进制附件
7、支持HTML格式(需要修改Content-Type')
[php]
CREATEORREPLACEPROCEDUREPROCSENDEMAIL(P_TXT VARCHAR2,
P_SUB VARCHAR2,
P_SENDOR VARCHAR2,
P_RECEIVER VARCHAR2,
P_SERVER VARCHAR2,
P_PORT NUMBERDEFAULT25,
P_NEED_SMTPINTDEFAULT0,
P_USER VARCHAR2DEFAULTNULL,
P_PASS VARCHAR2DEFAULTNULL,
P_FILENAME VARCHAR2DEFAULTNULL,
P_ENCODE VARCHAR2DEFAULT'bit7')
AUTHIDCURRENT_USERIS
/*
作用:
用oracle发送邮件
主要功能:
1、支持多收件人。
2、支持中文
3、支持大于32K的附件
4、支持多行正文
5、支持多附件
6、支持文本附件和二进制附件
7、支持HTML格式
作者:
suk
参数说明:
p_txt:
邮件正文
p_sub:
邮件标题
p_SendorAddress:
发送人邮件地址
p_ReceiverAddress:
接收地址,可以同时发送到多个地址上,地址之间用","或者";"隔开
p_EmailServer:
邮件服务器地址,可以是域名或者IP
p_Port:
邮件服务器端口
p_need_smtp:
是否需要smtp认证,0表示不需要,1表示需要
p_user:
smtp验证需要的用户名
p_pass:
smtp验证需要的密码
p_filename:
附件名称,必须包含完整的路径,如"d:
\temp\a.txt"。
可以有多个附件,附件名称只见用逗号或者分号分隔
p_encode:
附件编码转换格式,其中p_encode='bit7'表示文本类型附件
p_encode='base64'表示二进制类型附件
注意:
1、对于文本类型的附件,不能用base64的方式发送,否则出错
2、对于多个附件只能用同一种格式发送
*/
L_CRLFVARCHAR2
(2):
=UTL_TCP.CRLF;
L_SENDORADDRESSVARCHAR2(4000);
L_SPLITE VARCHAR2(10):
='++';
BOUNDARY CONSTANTVARCHAR2(256):
='-----BYSUK';
FIRST_BOUNDARY CONSTANTVARCHAR2(256):
='--'||BOUNDARY||L_CRLF;
LAST_BOUNDARY CONSTANTVARCHAR2(256):
='--'||BOUNDARY||'--'||
L_CRLF;
MULTIPART_MIME_TYPECONSTANTVARCHAR2(256):
='multipart/mixed;boundary="'||
BOUNDARY||'"';
/*以下部分是发送大二进制附件时用到的变量*/
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;/*ensuresproperformat; 2016*/
L_FILEPOS PLS_INTEGER:
=1;/*pointerforthefile*/
L_CHUNKS NUMBER;
L_BUF RAW(2100);
L_DATA RAW(2100);
L_MAX_LINE_WIDTH NUMBER:
=54;
L_DIRECTORY_BASE_NAMEVARCHAR2(100):
='DIR_FOR_SEND_MAIL';
L_LINE VARCHAR2(1000);
L_MESG VARCHAR2(32767);
/*以上部分是发送大二进制附件时用到的变量*/
TYPEADDRESS_LISTISTABLEOFVARCHAR2(100)INDEXBYBINARY_INTEGER;
MY_ADDRESS_LISTADDRESS_LIST;
TYPEACCT_LISTISTABLEOFVARCHAR2(100)INDEXBYBINARY_INTEGER;
MY_ACCT_LISTACCT_LIST;
-------------------------------------返回附件源文件所在目录或者名称--------------------------------------
FUNCTIONGET_FILE(P_FILEVARCHAR2,
P_GET INT)RETURNVARCHAR2IS
--p_get=1表示返回目录
--p_get=2表示返回文件名
L_FILEVARCHAR2(1000);
BEGIN
IFINSTR(P_FILE,'\')>0THEN
--windows
IFP_GET=1THEN
L_FILE:
=SUBSTR(P_FILE,1,INSTR(P_FILE,'\',-1)-1);
ELSIFP_GET=2THEN
L_FILE:
=SUBSTR(P_FILE,-(LENGTH(P_FILE)-INSTR(P_FILE,'\',-1)));
ENDIF;
ELSIFINSTR(P_FILE,'/')>0THEN
--linux/unix
IFP_GET=1THEN
L_FILE:
=SUBSTR(P_FILE,1,INSTR(P_FILE,'/',-1)-1);
ELSIFP_GET=2THEN
L_FILE:
=SUBSTR(P_FILE,-(LENGTH(P_FILE)-INSTR(P_FILE,'/',-1)));
ENDIF;
ENDIF;
RETURNL_FILE;
END;
---------------------------------------------删除directory------------------------------------
PROCEDUREDROP_DIRECTORY(P_DIRECTORY_NAMEVARCHAR2)IS
BEGIN
EXECUTEIMMEDIATE'dropdirectory'||P_DIRECTORY_NAME;
EXCEPTION
WHENOTHERSTHEN
NULL;
END;
--------------------------------------------------创建directory-----------------------------------------
PROCEDURECREATE_DIRECTORY(P_DIRECTORY_NAMEVARCHAR2,
P_DIR VARCHAR2)IS
BEGIN
EXECUTEIMMEDIATE'createdirectory'||P_DIRECTORY_NAME||'as'''||
P_DIR||'''';
EXECUTEIMMEDIATE'grantread,writeondirectory'||P_DIRECTORY_NAME||
'topublic';
EXCEPTION
WHENOTHERSTHEN
RAISE;
END;
--------------------------------------------分割邮件地址或者附件地址-----------------------------------
PROCEDUREP_SPLITE_STR(P_STR VARCHAR2,
P_SPLITE_FLAGINTDEFAULT1)IS
L_ADDRVARCHAR2(254):
='';
L_LEN INT;
L_STR VARCHAR2(4000);
J INT:
=0;--表示邮件地址或者附件的个数
BEGIN
/*处理接收邮件地址列表,包括去空格、将;转换为,等*/
L_STR:
=TRIM(RTRIM(REPLACE(REPLACE(P_STR,';',','),'',''),','));
L_LEN:
=LENGTH(L_STR);
FORIIN1..L_LENLOOP
IFSUBSTR(L_STR,I,1)<>','THEN
L_ADDR:
=L_ADDR||SUBSTR(L_STR,I,1);
ELSE
J:
=J+1;
IFP_SPLITE_FLAG=1THEN--表示处理邮件地址
--前后需要加上'<>',否则很多邮箱将不能发送邮件
L_ADDR:
='<'||L_ADDR||'>';
--调用邮件发送过程
MY_ADDRESS_LIST(J):
=L_ADDR;
ELSIFP_SPLITE_FLAG=2THEN--表示处理附件名称
MY_ACCT_LIST(J):
=L_ADDR;
ENDIF;
L_ADDR:
='';
ENDIF;
IFI=L_LENTHEN
J:
=J+1;
IFP_SPLITE_FLAG=1THEN
--调用邮件发送过程
L_ADDR:
='<'||L_ADDR||'>';
MY_ADDRESS_LIST(J):
=L_ADDR;
ELSIFP_SPLITE_FLAG=2THEN
MY_ACCT_LIST(J):
=L_ADDR;
ENDIF;
ENDIF;
ENDLOOP;
END;
------------------------------------------------写邮件头和邮件内容------------------------------------------
PROCEDUREWRITE_DATA(P_CONN INOUTNOCOPYUTL_SMTP.CONNECTION,
P_NAME INVARCHAR2,
P_VALUE INVARCHAR2,
P_SPLITEVARCHAR2DEFAULT':
',
P_CRLF VARCHAR2DEFAULTL_CRLF)IS
BEGIN
/*utl_raw.cast_to_raw对解决中文乱码问题很重要*/
UTL_SMTP.WRITE_RAW_DATA(P_CONN,UTL_RAW.CAST_TO_RAW(CONVERT(P_NAME||
P_SPLITE||
P_VALUE||
P_CRLF,'ZHS16GBK')));
END;
----------------------------------------写MIME邮件尾部-----------------------------------------------------
PROCEDUREEND_BOUNDARY(CONNINOUTNOCOPYUTL_SMTP.CONNECTION,
LASTINBOOLEANDEFAULTFALSE)IS
BEGIN
UTL_SMTP.WRITE_DATA(CONN,UTL_TCP.CRLF);
IF(LAST)THEN
UTL_SMTP.WRITE_DATA(CONN,LAST_BOUNDARY);
ENDIF;
END;
----------------------------------------------发送附件----------------------------------------------------
PROCEDUREATTACHMENT(CONN INOUTNOCOPYUTL_SMTP.CONNECTION,
MIME_TYPE INVARCHAR2DEFAULT'text/plain',
INLINE INBOOLEANDEFAULTTRUE,
FILENAME INVARCHAR2DEFAULT't.txt',
TRANSFER_ENCINVARCHAR2DEFAULT'7bit',
DT_NAME INVARCHAR2DEFAULT'0')IS
L_FILENAMEVARCHAR2(1000);
BEGIN
--写附件头
UTL_SMTP.WRITE_DATA(CONN,FIRST_BOUNDARY);
--设置附件格式
WRITE_DATA(CONN,'Content-Type',MIME_TYPE);
--如果文件名称非空,表示有附件
DROP_DIRECTORY(DT_NAME);
--创建directory
CREATE_DIRECTORY(DT_NAME,GET_FILE(FILENAME,1));
--得到附件文件名称
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||'"');
ENDIF;
--设置附件的转换格式
IF(TRANSFER_ENCISNOTNULL)THEN
WRITE_DATA(CONN,'Content-Transfer-Encoding',TRANSFER_ENC);
ENDIF;
UTL_SMTP.WRITE_DATA(CONN,UTL_TCP.CRLF);
--begin贴附件内容
IFTRANSFER_ENC='bit7'THEN
--如果是文本类型的附件
BEGIN
L_FILE_HANDLE:
=UTL_FILE.FOPEN(DT_NAME,L_FILENAME,'r');--打开文件
--把附件分成多份,这样可以发送超过32K的附件
LOOP
UTL_FILE.GET_LINE(L_FILE_HANDLE,L_LINE);
L_MESG:
=L_LINE||L_CRLF;
WRITE_DATA(CONN,'',L_MESG,'','');
ENDLOOP;
UTL_FILE.FCLOSE(L_FILE_HANDLE);
END_BOUNDARY(CONN);
EXCEPTION
WHENOTHERSTHEN
UTL_FILE.FCLOSE(L_FILE_HANDLE);
END_BOUNDARY(CONN);
NULL;
END;--结束文本类型附件的处理
ELSIFTRANSFER_ENC='base64'THEN
--如果是二进制类型的附件
BEGIN
--把附件分成多份,这样可以发送超过32K的附件
L_FILEPOS :
=1;--重置offset,在发送多个附件时,必须重置
L_FIL :
=BFILENAME(DT_NAME,L_FILENAME);