技术开发 频道

ORACLEERP开发基础之EBS开发基础

  EBS自定义邮件通知

  前面已经介绍过了EBS预警的功能,事实上Oracle数据库本身就有提供UTL_SIMPLE(ORACLE10g以后变成UTL_MAIL)包来实现邮件发送的功能,利用这个包可以开发出更灵活东西来。首先要安装utlsmtp.sql、utltcp.sql这两个包。

  ①发送带有URL邮件代码

  declare

  p_sender varchar2(30) := 'chongdong_wang@hek.cn';

  p_recipient varchar2(30) := 'jian_li2@hek.cn';

  p_subject varchar2(50) := '使用PL/SQL发送邮件';

  p_body long := '这是邮件正文内容啦!我又来啦!!!进行ORACLE ERP';

  mail_conn utl_smtp.connection;

  mail_host varchar2(15) := 'mail.hek.cn';

  user_name varchar2(156) := 'chongdong_wang@hek.cn';

  user_pwd varchar2(156) := '***';

  begin --创建一个TCP MAIL连接

  mail_conn := utl_smtp.open_connection(mail_host, 25);

  --ehlo与helo的区别:是否对邮件主机进行登陆认证

  --utl_smtp.helo(main_conn,mail_host);

  utl_smtp.ehlo(mail_conn, mail_host);

  --登陆认证语句 utl_smtp.command(mail_conn, 'AUTH LOGIN');

  --对用户及密码进行加密

  utl_smtp.command(mail_conn, demo_base64.encode(utl_raw.cast_to_raw(user_name)));

  utl_smtp.command(mail_conn, demo_base64.encode(utl_raw.cast_to_raw(user_pwd)));

  --指定发件人 utl_smtp.mail(mail_conn, p_sender);

  --指定收件人 utl_smtp.rcpt(mail_conn, p_recipient);

  --开始写邮件内容 utl_smtp.open_data(mail_conn);

  --指定显示的发件人,注意这边的显示的发件人可以上面指定发件人不同

  --这实际上是SMTP协议的缺陷,也是造成垃圾邮件主要原因

  utl_smtp.write_data(mail_conn, 'From:' || p_sender || utl_tcp.CRLF); utl_smtp.write_data(mail_conn, 'To:' || p_recipient || utl_tcp.crlf);

  --邮件主题:中文必须进行编码转换,否则会乱码 utl_smtp.write_raw_data(mail_conn, utl_raw.cast_to_raw(convert('Subject:' || p_subject || utl_tcp.CRLF, 'ZHS16GBK')));

  --设置邮件内容模式为HTML,也可以直接设置文本Content-Type:text/plain

  utl_smtp.write_raw_data(mail_conn, utl_raw.cast_to_raw(convert('Content-Type:text/html;

  charset=GBK' || utl_tcp.CRLF, 'ZHS16GBK')));

  utl_smtp.write_data(mail_conn, utl_tcp.CRLF);

  --邮件正文 utl_smtp.write_raw_data(mail_conn, utl_raw.cast_to_raw(convert(p_body, 'ZHS16GBK')));

  --关闭连接 utl_smtp.close_data(mail_conn); utl_smtp.quit(mail_conn); exception when utl_smtp.transient_error or utl_smtp.permanent_error then utl_smtp.quit(mail_conn);

  raise_application_error(-20000, sqlerrm);

  when others then raise_application_error(-20001, 'The send mail was error ' || sqlerrm);

  end;

  ②发送带有附件的邮件

  declare

  p_sender varchar2(30) := 'metalink@hek.cn';

  p_recipient varchar2(30) := 'chongdong_wang@hek.cn';

  p_subject varchar2(50) := 'PL/SQL发邮件、带链接、带附件';

  p_body long := 'PL/SQL发邮件、带链接带附件

  这是邮件正文内容啦!这是带附件的啦!!

  进行ORACLE ERP';

  mail_conn utl_smtp.connection;

  mail_host varchar2(15) := 'mail.hek.cn';

  user_name varchar2(156) := 'metalink@hek.cn';

  user_pwd varchar2(156) := 'metalink'; --发附件要用到的变量

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

  L_MESG VARCHAR2(32767);

  BOUNDARY CONSTANT VARCHAR2(256) := '-----7D81B75CCC90D2974F7A1CBD';

  FIRST_BOUNDARY CONSTANT VARCHAR2(256) := '--' || BOUNDARY || utl_tcp.CRLF;

  LAST_BOUNDARY CONSTANT VARCHAR2(256) := '--' || BOUNDARY || '--' || utl_tcp.CRLF;

  --发送带有附件邮件,MIME必须设为multipart/mixed

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

  begin

  --创建一个TCP MAIL连接

  mail_conn := utl_smtp.open_connection(mail_host, 25);

  --ehlo与helo的区别:是否对邮件主机进行登陆认证 -

  -utl_smtp.helo(main_conn,mail_host);

  utl_smtp.ehlo(mail_conn, mail_host);

  --登陆认证语句 utl_smtp.command(mail_conn, 'AUTH LOGIN');

  --对用户及密码进行加密

  utl_smtp.command(mail_conn, demo_base64.encode(utl_raw.cast_to_raw(user_name)));

  utl_smtp.command(mail_conn, demo_base64.encode(utl_raw.cast_to_raw(user_pwd)));

  --指定发件人

  utl_smtp.mail(mail_conn, p_sender); --指定收件人

  utl_smtp.rcpt(mail_conn, p_recipient); --开始写邮件内容

  utl_smtp.open_data(mail_conn);

  utl_smtp.write_data(mail_conn, 'From:' || p_sender || utl_tcp.CRLF);

  utl_smtp.write_data(mail_conn, 'To:' || p_recipient || utl_tcp.crlf);

  utl_smtp.write_data(mail_conn, 'Subject: ' || p_subject || utl_tcp.crlf);

  --中文编码转换

  utl_smtp.write_raw_data(mail_conn,utl_raw.cast_to_raw(convert('Subject:' ||p_subject ||utl_tcp.CRLF,'ZHS16GBK'))); utl_smtp.write_raw_data(mail_conn,utl_raw.cast_to_raw(convert('Content-Type:'||MULTIPART_MIME_TYPE||utl_tcp.CRLF,'ZHS16GBK')));

  --utl_tcp.CRLF 数据流行尾符

  utl_smtp.write_data(mail_conn, utl_tcp.CRLF); -

  -邮件正文

  utl_smtp.write_data(mail_CONN, FIRST_BOUNDARY);

  utl_smtp.write_raw_data(mail_conn,utl_raw.cast_to_raw(convert('Content-Type:text/html;charset=GB2312' ||utl_tcp.CRLF, 'ZHS16GBK')));

  utl_smtp.write_data(mail_conn, utl_tcp.CRLF);

  utl_smtp.write_raw_data(mail_conn,utl_raw.cast_to_raw(convert(p_body, 'ZHS16GBK')));

  utl_smtp.write_data(mail_conn, utl_tcp.CRLF);

  --附件格式

  utl_smtp.write_data(mail_CONN, FIRST_BOUNDARY);

  utl_smtp.write_raw_data(mail_conn,utl_raw.cast_to_raw(convert('Content-Type:text/html;charset=GB2312' ||utl_tcp.CRLF, 'ZHS16GBK')));

  utl_smtp.WRITE_RAW_DATA(mail_conn, UTL_RAW.CAST_TO_RAW(CONVERT('Content-Disposition' || ':' ||'attachment;filename="'||'qq.xls"' || utl_tcp.CRLF, 'ZHS16GBK')));

  utl_smtp.write_raw_data(mail_conn,utl_raw.cast_to_raw(convert('Content-Transfer-Encoding:base64'||utl_tcp.CRLF,'ZHS16GBK')));

  utl_smtp.write_data(mail_CONN, UTL_TCP.CRLF);

  --附件二进制流

  BEGIN

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

  L_FILEPOS := 1;

  --CREATE OR REPLACE DIRECTORY U_FIEL AS '/data/book/'

  --qq.xls附件放在ORACLE服务器/data/book/下,注意大写

  L_FIL := BFILENAME('U_FIEL', 'qq.xls');

  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(MAIL_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);

  EXCEPTION WHEN OTHERS THEN DBMS_LOB.FILECLOSE(L_FIL);

  utl_smtp.WRITE_DATA(mail_CONN, UTL_TCP.CRLF);

  RAISE;

  END;

  --结束处理二进制附件

  --关闭连接

  utl_smtp.close_data(mail_conn); utl_smtp.quit(mail_conn);

  exception when utl_smtp.transient_error or

  utl_smtp.permanent_error then utl_smtp.quit(mail_conn);

  raise_application_error(-20000, sqlerrm);

  when others then

  utl_smtp.quit(mail_conn);

  DBMS_OUTPUT.put_line(sqlerrm);

  end;

6
相关文章