oracle报请发送文件,用oracle发送邮件

CREATEORREPLACE PROCEDURE PROCSENDEMAIL(P_TXT       VARCHAR2,P_SUB       VARCHAR2,P_SENDOR    VARCHAR2,P_RECEIVER  VARCHAR2,P_SERVER    VARCHAR2,P_PORT      NUMBERDEFAULT25,P_NEED_SMTP INTDEFAULT0,P_USER      VARCHAR2DEFAULTNULL,P_PASS      VARCHAR2DEFAULTNULL,P_FILENAME  VARCHAR2DEFAULTNULL,P_ENCODE    VARCHAR2DEFAULT'bit 7')AUTHID CURRENT_USER IS/*

作用:用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:\tempa.txt"。

可以有多个附件,附件名称只见用逗号或者分号分隔

p_encode:附件编码转换格式,其中 p_encode='bit 7' 表示文本类型附件

p_encode='base64' 表示二进制类型附件

注意:

1、对于文本类型的附件,不能用base64的方式发送,否则出错

2、对于多个附件只能用同一种格式发送

*/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||'"';/* 以下部分是发送大二进制附件时用到的变量 */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(100) :='DIR_FOR_SEND_MAIL';L_LINE                VARCHAR2(1000);L_MESG                VARCHAR2(32767);/* 以上部分是发送大二进制附件时用到的变量 */TYPE ADDRESS_LIST IS TABLE OF VARCHAR2(100)INDEX BY BINARY_INTEGER;MY_ADDRESS_LIST ADDRESS_LIST;TYPE ACCT_LIST IS TABLE OF VARCHAR2(100)INDEX BY BINARY_INTEGER;MY_ACCT_LIST ACCT_LIST;

-------------------------------------返回附件源文件所在目录或者名称--------------------------------------

FUNCTIONGET_FILE(P_FILE VARCHAR2,P_GET  INT) RETURNVARCHAR2 IS--p_get=1 表示返回目录--p_get=2 表示返回文件名

L_FILE VARCHAR2(1000);BEGINIFINSTR(P_FILE,'') >0 THEN--windowsIFP_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)));ENDIF;ELSIF INSTR(P_FILE,'/') >0 THEN--linux/unixIFP_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)));ENDIF;ENDIF;

RETURNL_FILE;END;

---------------------------------------------删除directory------------------------------------PROCEDURE DROP_DIRECTORY(P_DIRECTORY_NAME VARCHAR2)IS

BEGIN

EXECUTE IMMEDIATE'drop directory '||P_DIRECTORY_NAME;EXCEPTION

WHEN OTHERS THEN

NULL;END;

--------------------------------------------------创建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;

--------------------------------------------分割邮件地址或者附件地址-----------------------------------PROCEDURE P_SPLITE_STR(P_STR         VARCHAR2,P_SPLITE_FLAG INTDEFAULT1)IS

L_ADDR VARCHAR2(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);

FORI IN 1..L_LEN LOOPIFSUBSTR(L_STR,I,1) <>','THEN

L_ADDR:=L_ADDR||SUBSTR(L_STR,I,1);

ELSEJ:=J+1;

IFP_SPLITE_FLAG=1 THEN--表示处理邮件地址--前后需要加上'<>',否则很多邮箱将不能发送邮件

L_ADDR:='||L_ADDR||'>';

--调用邮件发送过程

MY_ADDRESS_LIST(J) :=L_ADDR;ELSIF P_SPLITE_FLAG=2 THEN--表示处理附件名称

MY_ACCT_LIST(J) :=L_ADDR;ENDIF;L_ADDR:='';ENDIF;

IFI=L_LEN THEN

J:=J+1;

IFP_SPLITE_FLAG=1 THEN--调用邮件发送过程

L_ADDR:='||L_ADDR||'>';MY_ADDRESS_LIST(J) :=L_ADDR;ELSIF P_SPLITE_FLAG=2 THEN

MY_ACCT_LIST(J) :=L_ADDR;ENDIF;ENDIF;END LOOP;END;

------------------------------------------------写邮件头和邮件内容------------------------------------------PROCEDURE WRITE_DATA(P_CONN   IN OUT NOCOPY UTL_SMTP.CONNECTION,P_NAME   IN VARCHAR2,P_VALUE  IN VARCHAR2,P_SPLITE VARCHAR2DEFAULT':',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邮件尾部-----------------------------------------------------PROCEDURE END_BOUNDARY(CONN IN OUT NOCOPY UTL_SMTP.CONNECTION,LAST IN BOOLEANDEFAULTFALSE)IS

BEGIN

UTL_SMTP.WRITE_DATA(CONN,UTL_TCP.CRLF);

IF (LAST)THEN

UTL_SMTP.WRITE_DATA(CONN,LAST_BOUNDARY);ENDIF;END;

----------------------------------------------发送附件----------------------------------------------------PROCEDURE ATTACHMENT(CONN         IN OUT NOCOPY UTL_SMTP.CONNECTION,MIME_TYPE    IN VARCHAR2DEFAULT'text/plain',INLINE       IN BOOLEANDEFAULTTRUE,FILENAME     IN VARCHAR2DEFAULT't.txt',TRANSFER_ENC IN VARCHAR2DEFAULT'7 bit',DT_NAME      IN VARCHAR2DEFAULT'0')IS

L_FILENAME VARCHAR2(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||'"');

ELSEWRITE_DATA(CONN,'Content-Disposition','attachment; filename="'||L_FILENAME||'"');ENDIF;

--设置附件的转换格式IF (TRANSFER_ENC IS NOT NULL)THEN

WRITE_DATA(CONN,'Content-Transfer-Encoding',TRANSFER_ENC);ENDIF;UTL_SMTP.WRITE_DATA(CONN,UTL_TCP.CRLF);

--begin 贴附件内容IFTRANSFER_ENC='bit 7'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,'','');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; --结束文本类型附件的处理

ELSIF TRANSFER_ENC='base64'THEN--如果是二进制类型的附件

BEGIN--把附件分成多份,这样可以发送超过32K的附件

L_FILEPOS:=1;--重置offset,在发送多个附件时,必须重置

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;ENDIF;DBMS_LOB.FILEOPEN(L_FIL,DBMS_LOB.FILE_READONLY);DBMS_LOB.READ(L_FIL,L_AMT,L_FILEPOS,L_BUF);L_DATA:=NULL;

FORI 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;ENDIF;UTL_SMTP.来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/87010/viewspace-400071/,如需转载,请注明出处,否则将追究法律责任。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Oracle数据库可以使用UTL_SMTP包发送电子邮件。UTL_SMTP是Oracle提供的一个包,可以通过SMTP协议发送电子邮件。下面是一个简单的例子,展示如何使用UTL_SMTP包在Oracle数据库中自动发送电子邮件。 假设你已经有了一个包含要发送电子邮件的收件人地址、主题和正文的表。以下是使用UTL_SMTP包发送电子邮件的步骤: 1. 首先,你需要在Oracle数据库中启用UTL_SMTP包。你可以使用以下命令启用UTL_SMTP包: ```sql EXECUTE UTL_MAIL.ENABLE; ``` 2. 接下来,你需要编写一个存储过程,该存储过程从包含电子邮件数据的表中选择数据,并使用UTL_SMTP包发送电子邮件。以下是一个例子: ```sql CREATE OR REPLACE PROCEDURE send_email AS -- 声明变量 v_mailhost VARCHAR2(255) := 'your_mail_host'; v_port NUMBER := 25; v_sender VARCHAR2(255) := 'sender_email'; v_username VARCHAR2(255) := 'sender_username'; v_password VARCHAR2(255) := 'sender_password'; v_recipient VARCHAR2(255); v_subject VARCHAR2(255); v_message VARCHAR2(4000); v_conn UTL_SMTP.CONNECTION; BEGIN -- 连接SMTP服务器 v_conn := UTL_SMTP.OPEN_CONNECTION(v_mailhost, v_port); UTL_SMTP.HELO(v_conn, v_mailhost); UTL_SMTP.AUTH(v_conn, v_username, v_password); -- 循环遍历邮件表中的每一行数据 FOR r_email IN (SELECT recipient, subject, message FROM email_table) LOOP -- 设置收件人地址、主题和正文 v_recipient := r_email.recipient; v_subject := r_email.subject; v_message := r_email.message; -- 发送电子邮件 UTL_SMTP.MAIL(v_conn, v_sender); UTL_SMTP.RCPT(v_conn, v_recipient); UTL_SMTP.DATA(v_conn, 'Subject: ' || v_subject || UTL_TCP.CRLF || 'To: ' || v_recipient || UTL_TCP.CRLF || 'From: ' || v_sender || UTL_TCP.CRLF || UTL_TCP.CRLF || v_message); END LOOP; -- 关闭连接 UTL_SMTP.QUIT(v_conn); EXCEPTION -- 处理异常 WHEN OTHERS THEN UTL_SMTP.CLOSE_CONNECTION(v_conn); RAISE; END; ``` 在上面的存储过程中,你需要将 `v_mailhost`、`v_port`、`v_sender`、`v_username` 和 `v_password` 替换为你自己的邮件服务器和发件人信息。该存储过程从 `email_table` 表中选择数据,并将每个电子邮件发送给相应的收件人。 3. 最后,你可以使用以下命令调用存储过程并发送电子邮件: ```sql EXECUTE send_email; ``` 这将会发送 `email_table` 表中的所有电子邮件。你可以在表中添加或删除数据,以控制要发送的电子邮件。 需要注意的是,为了使用UTL_SMTP包,你需要有相应的权限。另外,如果你的邮件服务器需要SSL或TLS连接,你需要使用UTL_SMTP包的SSL或TLS版本。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值