http://baser.blog.51cto.com/4153192/871086
收件人只有一個的過程如下:
recipient IN VARCHAR2, --接收人
subject IN VARCHAR2, --郵件主題
message IN VARCHAR2) IS --郵件內容
mailhost VARCHAR2(30) := 'smtp.sina.com' ; --新浪郵箱服務器
c utl_smtp.connection;
msg VARCHAR2(1000);
BEGIN
msg := 'Date: ' || to_char(SYSDATE - 1, 'dd mon yy hh24:mi:ss') ||
utl_tcp.crlf || 'From: <' || sender || '>' || utl_tcp.crlf ||
'subject: ' || subject || utl_tcp.crlf || 'To: <' || recipient || '>' ||
utl_tcp.crlf || '' || utl_tcp.crlf || message;
c := utl_smtp.open_connection(mailhost, 25);
utl_smtp.command(c, 'auth login'); --1
utl_smtp.command(c, --2
utl_raw.cast_to_varchar2(utl_encode.base64_encode(utl_raw.cast_to_raw('用戶名')))); --3 --發送郵箱用戶名
utl_smtp.command(c, --4
utl_raw.cast_to_varchar2(utl_encode.base64_encode(utl_raw.cast_to_raw('密碼'))));--5 --發送郵箱密碼
utl_smtp.helo(c, mailhost);
utl_smtp.mail(c, sender);
utl_smtp.rcpt(c, recipient);
utl_smtp.open_data(c);
utl_smtp.write_raw_data(c, utl_raw.cast_to_raw(msg));
utl_smtp.close_data(c);
utl_smtp.quit(c);
EXCEPTION
WHEN utl_smtp.transient_error OR utl_smtp.permanent_error THEN
BEGIN
utl_smtp.quit(c);
EXCEPTION
WHEN OTHERS THEN
NULL;
END;
WHEN OTHERS THEN
dbms_output.put_line(SQLERRM);
END p_mail_sina;
注意事項:
1.由於在測試中我采用的都是外網的方式發送接收郵件,因此必須加上用黃色圈出的這部分代碼進行認證。內網內部發送就不需要了,不過沒測試。
2. 黃色圈出的這部分代碼第三行和第五行填寫的內容分別是郵箱服務器對應的郵箱用戶名和密碼。
3.用於發送的郵箱的服務器必須創建acl,主要是三個步驟
1)創建訪問控制列表acl
BEGIN
acl => 'email_server_permissions.xml',
description => 'Enables network permissions for the e-mail server',
principal => 'database_user',--進行操作的數據庫用戶且用戶要大寫
is_grant => TRUE,
privilege => 'connect');
END;
2)將ACL與郵件服務器關聯(這一步,采用不同的郵箱服務器就需要分別執行,如想用qq郵箱發送,那么就必須換成qq郵箱服務器執行一遍)
DBMS_NETWORK_ACL_ADMIN.assign_acl (
acl => 'email_server_permissions.xml',
host => 'smtp.sina.com', /*新浪的郵箱服務器地址,如果是用qq作為發送郵件,
則用qq郵箱服務器地址smtp.qq.com*/
lower_port => 25,
upper_port => NULL);
COMMIT;
END;
關聯后,可用dba_network_acls查看是否已經生成
3)為執行的數據庫用戶授予連接郵件服務器的權限
dbms_network_acl_admin.add_privilege(
acl => 'email_server_permissions.xml',
principal =>'database_user',--進行操作的數據庫用戶且用戶要大寫
is_grant => TRUE,
privilege => 'connect');
END;
采用dba_network_acl_privileges視圖查看授予的權限
principal,
privilege,
is_grant,
TO_CHAR(start_date, 'DD-MON-YYYY') AS start_date,
TO_CHAR(end_date, 'DD-MON-YYYY') AS end_date
FROM sys.dba_network_acl_privileges;
4.utl_tcp.crlf作用:換行
注意在寫郵件標題,發送人,接收人,郵件內容時,各個之間一定要有換行,否則會無法發送或者是郵件內容為空。
5.中文亂碼問題
utl_smtp.write_raw_data 用該過程替代utl_smtp.write_data可以解決中文亂碼的問題。
6.自己測試中發現如果采用qq郵箱發送郵件,則
發給多個人
recipient1 IN VARCHAR2,
recipient2 IN VARCHAR2,
recipient3 IN VARCHAR2,
subject IN VARCHAR2,
message IN VARCHAR2) IS
mailhost VARCHAR2(30) := 'smtp.qq.com';
c utl_smtp.connection;
msg VARCHAR2(1000);
BEGIN
msg := 'Date: ' || to_char(SYSDATE - 1, 'dd mon yy hh24:mi:ss') ||
utl_tcp.crlf || 'From: <' || sender || '>' || utl_tcp.crlf ||
'subject: ' || subject || utl_tcp.crlf || 'To: <' || recipient1 ||
'>;<' || recipient2 || '>' || utl_tcp.crlf || 'Cc: <' ||
recipient3 || '>' || utl_tcp.crlf || '' || utl_tcp.crlf ||
message;
c := utl_smtp.open_connection(mailhost, 25);
utl_smtp.helo(c, mailhost);
utl_smtp.command(c, 'auth login');
utl_smtp.command(c,
utl_raw.cast_to_varchar2(utl_encode.base64_encode(utl_raw.cast_to_raw(sender))));
utl_smtp.command(c,
utl_raw.cast_to_varchar2(utl_encode.base64_encode(utl_raw.cast_to_raw('password'))));
utl_smtp.mail(c, sender);
utl_smtp.rcpt(c, recipient1);
utl_smtp.rcpt(c, recipient2);
utl_smtp.rcpt(c, recipient3);
utl_smtp.open_data(c);
utl_smtp.write_raw_data(c, utl_raw.cast_to_raw(msg));
utl_smtp.close_data(c);
utl_smtp.quit(c);
END p_sendmailto_many;