ORACLE发送邮件
1.前提
记录数据库发送邮件的方式:
前提:通过UTL_SMTP格式发送邮件,
2.了解
UTL_SMTP.write_data 和 UTL_SMTP.write_raw_data 是两个不同的函数,它们各自有不同的用途:
UTL_SMTP.write_data:
这个函数用于向SMTP服务器发送普通的字符串数据。它接收一个字符串参数,并直接将该字符串发送出去。这通常用于发送邮件的头部信息(如 To:、From:、Subject: 等字段),这些字段通常只包含ASCII字符。
示例:
plsql
UTL_SMTP.write_data(l_mail_conn, 'To: ' || l_receiver || UTL_TCP.crlf);
UTL_SMTP.write_raw_data:
这个函数用于发送原始的字节数据。它接收一个RAW类型的参数,并将这组字节直接发送到SMTP服务器。这在需要发送非ASCII字符(如中文)时特别有用,因为非ASCII字符需要先转换为字节流才能正确发送。
示例:
plsql
UTL_SMTP.write_raw_data(l_mail_conn, UTL_RAW.cast_to_raw(convert(l_subject || UTL_TCP.crlf, 'AL32UTF8')));
在这个例子中,l_subject 包含了邮件的主题,可能包含中文字符。convert 函数将字符串从数据库字符集转换为 AL32UTF8 字符集,然后 UTL_RAW.cast_to_raw 将转换后的字符串转换为RAW类型,以便通过 write_raw_data 发送。
在发送包含中文字符的邮件时,你应该使用 UTL_SMTP.write_raw_data 来发送邮件头部和正文,以确保中文字符能够正确编码并发送。而对于只包含ASCII字符的头部字段(如 Date:、To:、From: 等),可以使用 UTL_SMTP.write_data。
确保在发送邮件正文之前已经正确地设置了 Content-Type 头部,以指定邮件正文使用的字符集(如 text/plain; charset="UTF-8"),这样接收者的邮件客户端才能正确地解析和显示中文字符。
3.代码示例
贴上用来测试的代码:
plsql
DECLARE
/*********************************************************************
使用的SMTP服务器(smtp.163.com)可能需要特定的端口(如465或587)和加密方式(SSL或TLS)。
如果端口25不支持,或者没有正确配置加密,那么邮件可能不会被发送或接收。
确保您的邮件服务提供商允许您使用第三方程序发送邮件,
并且没有因为安全原因(如IP地址黑名单)而阻止您的发送。
*********************************************************************/
l_mail_conn UTL_SMTP.connection; -- 到邮件服务器的连接
l_mail_host VARCHAR2(150) := 'smtp.163.com'; -- SMTP服务器地址
l_subject VARCHAR2(30) := '验证码'; -- 邮件标题
l_message VARCHAR2(32767) := '验证码为:1223456'; -- 邮件正文
l_sender VARCHAR2(150) := '****@163.com'; -- 登录SMTP服务器的用户名
l_password VARCHAR2(150) := '****'; -- 登录SMTP服务器的密码
l_receiver VARCHAR2(150) := '****@163.com'; -- 发送者邮箱地址
v_recipient VARCHAR2(150) := '****@qq.com'; -- 邮件接收人
CHARACTER_SET VARCHAR2(150) := 'AL32UTF8';
BEGIN
-- 打开到SMTP服务器的连接
l_mail_conn := UTL_SMTP.open_connection(l_mail_host, 25);
-- 发送EHLO命令
UTL_SMTP.ehlo(l_mail_conn, l_mail_host);
-- SMTP服务器登录校验
UTL_SMTP.command(l_mail_conn, 'AUTH LOGIN');
UTL_SMTP.command(l_mail_conn, UTL_RAW.cast_to_varchar2(UTL_ENCODE.base64_encode(UTL_RAW.cast_to_raw(l_sender))));
UTL_SMTP.command(l_mail_conn, UTL_RAW.cast_to_varchar2(UTL_ENCODE.base64_encode(UTL_RAW.cast_to_raw(l_password))));
-- 发件人
UTL_SMTP.mail(l_mail_conn, l_receiver);
-- 收件人
UTL_SMTP.rcpt(l_mail_conn, v_recipient);
-- 开始发送邮件数据
UTL_SMTP.open_data(l_mail_conn);
-- 创建邮件头
UTL_SMTP.write_raw_data(l_mail_conn, UTL_RAW.cast_to_raw(convert('Date: ' || TO_CHAR(SYSDATE, 'dd mon yy hh24:mi:ss') || UTL_TCP.crlf, CHARACTER_SET)));
UTL_SMTP.write_raw_data(l_mail_conn, UTL_RAW.cast_to_raw(convert('To: ' || l_receiver || UTL_TCP.crlf, CHARACTER_SET)));
UTL_SMTP.write_raw_data(l_mail_conn, UTL_RAW.cast_to_raw(convert('From: ' || l_sender || UTL_TCP.crlf, CHARACTER_SET)));
UTL_SMTP.write_raw_data(l_mail_conn, UTL_RAW.cast_to_raw(convert('Subject: ' || l_subject || UTL_TCP.crlf, CHARACTER_SET))); -- 标题
UTL_SMTP.write_raw_data(l_mail_conn, UTL_RAW.cast_to_raw(convert('Content-Type: text/plain; charset="UTF-8'|| UTL_TCP.CRLF, CHARACTER_SET)));
UTL_SMTP.write_data(l_mail_conn, UTL_TCP.crlf); -- 空行,标志着数据头部分的结束
-- 邮件正文
UTL_SMTP.write_raw_data(l_mail_conn, UTL_RAW.cast_to_raw(convert(l_message|| UTL_TCP.crlf, CHARACTER_SET)));
UTL_SMTP.close_data(l_mail_conn); --结束邮件
UTL_SMTP.quit(l_mail_conn); -- 关闭SMTP服务器连接
DBMS_OUTPUT.PUT_LINE('Email发送成功');
EXCEPTION
WHEN OTHERS THEN
-- 打印错误堆栈信息
DBMS_OUTPUT.PUT_LINE('错误信息: ' || SQLERRM);
END;