项目上有一个需求,当培训课开始报名时,需要向相关的人员发送邮件来通知大家,不是手动,而是在数据库定点自动发送邮件。
实现思路:在存储过程里面向发送邮件相关的表里面添加数据,然后当添加数据时在触发器触发发送邮件的事件,即调用发送邮件的存储过程,发送邮件的存储过程如下:
PROCEDURE P_SEND_MAIL(p_recipient VARCHAR2, -- 邮件接收人 p_subject VARCHAR2, -- 邮件标题 p_message VARCHAR2 -- 邮件正文 ) IS --下面四个变量请根据实际邮件服务器进行赋值 v_mailhost VARCHAR2(30) := ' '; --SMTP服务器地址 v_user VARCHAR2(30) := ' '; --登录SMTP服务器的用户名;只是用户名, v_pass VARCHAR2(20) := ' '; --登录SMTP服务器的密码 v_sender VARCHAR2(50) := ' '; --发送都邮箱,一般与 ps_user 对应 v_conn UTL_SMTP.connection; --到邮件服务器的连接 v_msg varchar2(4000); --邮件内容 BEGIN v_conn := UTL_SMTP.open_connection(v_mailhost, 25); UTL_SMTP.ehlo(v_conn, v_mailhost); --是用 ehlo() 而不是 helo() 函数 --否则会报:ORA-29279: SMTP 永久性错误: 503 5.5.2 Send hello first. --UTL_SMTP.helo(v_conn,v_mailhost); --免费邮箱需要服务器登录校验 ;公司邮箱可能不需要校验. UTL_SMTP.command(v_conn, 'AUTH LOGIN'); -- smtp服务器登录校验 UTL_SMTP.command(v_conn,UTL_RAW.cast_to_varchar2(UTL_ENCODE.base64_encode(UTL_RAW.cast_to_raw(v_user)))); UTL_SMTP.command(v_conn,UTL_RAW.cast_to_varchar2(UTL_ENCODE.base64_encode(UTL_RAW.cast_to_raw(v_pass)))); UTL_SMTP.mail(v_conn, '<' || v_sender || '>'); --设置发件人 UTL_SMTP.rcpt(v_conn, '<' || p_recipient || '>'); --设置收件人 -- 创建要发送的邮件内容注意报头信息和邮件正文之间要空一行 v_msg := 'MIME-Version: 1.0' || UTL_TCP.CRLF ||'Content-type: text/html;Charset=ZHS16GBK' || UTL_TCP.CRLF || 'Date:' || TO_CHAR(SYSDATE, 'dd mon yy hh24:mi:ss') || -- UTL_TCP.CRLF || 'From: ' || v_sender || '<' || v_sender || '>' || UTL_TCP.CRLF || 'From: '||convert('财务共享服务中心平台 ','ZHS16CGB231280')||-- || v_sender || '<' || v_sender || '>' || UTL_TCP.CRLF || 'To: ' || p_recipient || '<' || p_recipient || '>' || UTL_TCP.CRLF || 'Subject: ' || convert(p_subject||' ','ZHS16CGB231280') || UTL_TCP.CRLF || UTL_TCP.CRLF || -- 这前面是报头信息 UTL_TCP.CRLF || UTL_TCP.CRLF || convert(p_message||' ','ZHS16CGB231280') || -- 这个是邮件正文 UTL_TCP.CRLF ||convert(' ','ZHS16CGB231280')|| UTL_TCP.CRLF ||UTL_TCP.CRLF ||convert('注:这是系统发送的邮件,无需回复。 ','ZHS16CGB231280');
UTL_SMTP.open_data(v_conn); --打开流 UTL_SMTP.write_raw_data(v_conn, UTL_RAW.cast_to_raw(v_msg)); --这样写标题和内容都能用中文 UTL_SMTP.close_data(v_conn); --关闭流 UTL_SMTP.quit(v_conn); --关闭连接 P_SEND_MAIL_LOG(p_recipient,p_subject,v_msg,'SUCCESS'); EXCEPTION WHEN OTHERS THEN /* DBMS_OUTPUT.put_line(DBMS_UTILITY.format_error_stack); DBMS_OUTPUT.put_line(DBMS_UTILITY.format_call_stack);*/ P_SEND_MAIL_LOG(p_recipient,p_subject,v_msg,'FAILURE'); END; PROCEDURE P_SEND_MAIL_TRIGGER(V_MSG_TYPE VARCHAR2, V_MSG_ID VARCHAR2, V_MSG_CONTENT VARCHAR2, V_RECEIVE_USER VARCHAR2) AS V_TITLE VARCHAR2(200); V_PERSON_MAIL VARCHAR2(64); BEGIN IF V_MSG_TYPE = 'KHTZ' THEN V_TITLE := '关于xxxx的通知'; ELSIF V_MSG_TYPE = 'KH' THEN V_TITLE := '关于xxxx通知'; ELSIF V_MSG_TYPE = 'SX' THEN V_TITLE := 'xxxx通知'; ELSIF V_MSG_TYPE='QF' THEN SELECT T.MASSTEXT_TITLE INTO V_TITLE FROM AMC_SMS_MASS_TEXT T WHERE T.ID=V_MSG_ID; ELSIF V_MSG_TYPE = 'MS' THEN V_TITLE := '关于xxxx的通知'; ELSIF V_MSG_TYPE = 'KHMB' THEN V_TITLE := '关于xxxx的通知'; ELSIF V_MSG_TYPE = 'PXGL' THEN V_TITLE := '关于xxx的通知'; END IF; SELECT NVL(T.ATTRIBUTE8, 'NULL') INTO V_PERSON_MAIL FROM AMC_PERSON_V T WHERE T.PERSON_NO = V_RECEIVE_USER AND ROWNUM=1; P_SEND_MAIL(V_PERSON_MAIL, V_TITLE, V_MSG_CONTENT); END;
---------------日志 PROCEDURE P_SEND_MAIL_LOG(V_MAIL_RECEICER VARCHAR2, V_MSG_TITLE VARCHAR2, V_MSG_CONTENT VARCHAR2, V_MAIL_STATUS VARCHAR2) AS BEGIN INSERT INTO MAIL_BOX_LOG (MAIL_RECEICER, MSG_TITLE, MSG_CONTENT, MAIL_SENDTIME, MAIL_STATUS) VALUES (V_MAIL_RECEICER, V_MSG_TITLE, V_MSG_CONTENT, SYSDATE, V_MAIL_STATUS); END;
