Oracle 預存程序中發送郵件,並支援使用者驗證、中文標題和內容

來源:互聯網
上載者:User

 在 Oracle
的預存程序執行中,我們可能希望它本身能完成郵件發送執行的結果,特別是在捕獲到了異常時。不能總是依賴於調用預存程序的外部程式--調用後,根據出口參
數,發送執行結果。這一需求更迫切的表現在非人工參與的 Oracle Job 調用預存程序的情況下。

所幸,Oracle
為我們提供了發送郵件的工具包 UTL_SMTP,它最早出現在 Oracle 8.1.7
版本中。下面是我從網路上搜尋相關資料後、綜合整理、多處修正、數次調試、排除萬難而寫出的一個發送郵件的預存程序。可支援需使用者驗證的郵件伺服器,中文
標題和中文內容無亂碼,只還未支援附件的發送,相信這方面應用較少,需要的話再 Google 一下,且文後參考中有相應的連結。

view source

print
?01.
CREATE
OR
REPLACE
PROCEDURE
send_mail(

02.
     
p_recipient VARCHAR2,
-- 郵件接收人

03.
     
p_subject   VARCHAR2,
-- 郵件標題

04.
     
p_message   VARCHAR2 
-- 郵件內文

05.
)

06.
IS

07.
 
08.
    
--下面四個變數請根據實際郵件伺服器進行賦值

09.
    
v_mailhost  VARCHAR2(30) :=
'mail.xxx.com'
;    
--SMTP伺服器位址

10.
    
v_user      VARCHAR2(30) :=
'user'
;
--登入SMTP伺服器的使用者名稱

11.
    
v_pass      VARCHAR2(20) :=
'pass'
;         
--登入SMTP伺服器的密碼

12.
    
v_sender    VARCHAR2(50)  :=
'user@xxx.com'
;
--發送都郵箱,一般與 ps_user 對應

13.
    
 
14.
    
v_conn  UTL_SMTP.
connection
;
--到郵件伺服器的串連

15.
    
v_msg varchar2(4000); 
--郵件內容

16.
 
17.
BEGIN

18.
 
19.
    
v_conn := UTL_SMTP.open_connection(v_mailhost, 25);

20.
    
UTL_SMTP.ehlo(v_conn, v_mailhost);
--是用 ehlo() 而不是 helo() 函數

21.
    
--否則會報:ORA-29279: SMTP 永久性錯誤: 503 5.5.2 Send hello first.

22.
 
23.
    
UTL_SMTP.command(v_conn,
'AUTH LOGIN'
);  
-- smtp伺服器登入校正

24.
    
UTL_SMTP.command(v_conn,UTL_RAW.cast_to_varchar2(UTL_ENCODE.base64_encode(UTL_RAW.cast_to_raw(v_user))));

25.
    
UTL_SMTP.command(v_conn,UTL_RAW.cast_to_varchar2(UTL_ENCODE.base64_encode(UTL_RAW.cast_to_raw(v_pass))));

26.
 
27.
    
UTL_SMTP.mail(v_conn, v_sender);    
--設定寄件者

28.
    
UTL_SMTP.rcpt(v_conn, p_recipient); 
--設定收件者

29.
 
30.
    
-- 建立要發送的郵件內容 注意前序資訊和郵件內文之間要空一行

31.
    
v_msg :=
'Date:'
|| TO_CHAR(SYSDATE,
'dd mon yy hh24:mi:ss'
)

32.
        
|| UTL_TCP.CRLF ||
'From: '
|| v_sender ||
'<'
|| v_sender ||
'>'

33.
        
|| UTL_TCP.CRLF ||
'To: '
  || p_recipient ||
'<'
|| p_recipient ||
'>'

34.
        
|| UTL_TCP.CRLF ||
'Subject: '
|| p_subject

35.
        
|| UTL_TCP.CRLF || UTL_TCP.CRLF 
-- 這前面是前序資訊

36.
        
|| p_message;   
-- 這個是郵件內文

37.
 
38.
    
UTL_SMTP.open_data(v_conn);
--開啟流

39.
    
UTL_SMTP.write_raw_data(v_conn, UTL_RAW.cast_to_raw(v_msg));
--這樣寫標題和內容都能用中文

40.
    
UTL_SMTP.close_data(v_conn);
--關閉流

41.
    
UTL_SMTP.quit(v_conn);
--關閉串連

42.
    
 
43.
EXCEPTION

44.
 
45.
    
WHEN
OTHERS
THEN

46.
        
DBMS_OUTPUT.put_line(DBMS_UTILITY.format_error_stack);

47.
        
DBMS_OUTPUT.put_line(DBMS_UTILITY.format_call_stack);

48.
 
49.
END
send_mail;

上面代碼在 Oracle 9.2.0(Solaris 平台,資料庫字元集是 ZHS16GBK) 中實際運行後通過,在 PL/SQL Developer 的 SQL Window 中用下面代碼調用該預存程序:

begin
    send_mail(
'fantasia@sina.com','

中文標題','中文內容');
end;


而且在 PL/SQL Developer 的 Command Windows 或是 SQL *Plus 中執行:

send_mail(
'fantasia@sina.com','

中文標題','中文內容');

都能正常發送,成功收到郵件,並且標題和內容的中文顯示正常。

網路上直接拿下來的例子,多是沒有很好的解決中文文題,有些不能支援郵件伺服器的驗證,當今時代要找個不需要使用者驗證的郵件伺服器太難了。關鍵是有個致命問題是,一運行就報類似如下的錯誤:

ORA-29279: SMTP 永久性錯誤: 503 5.5.2 Send hello first.

----- PL/SQL Call Stack -----
  object      line  object
  handle    number  name
38298bd60        45  procedure TCSM.SEND_MAIL
38a4efa40         2  anonymous block

原因是:若郵件伺服器需要使用者驗證時,對郵件伺服器打招呼的方式不對,不能寫成
 
UTL_SMTP.helo(v_conn, v_mailhost);


而要寫成:

UTL_SMTP.ehlo(v_conn, v_mailhost);


如果你的郵件中只用英文,那麼上面代碼中的三行:

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.DATA (mail_conn, v_msg);


也可以把郵件前序和本文資訊分開來寫入到串連中去,但這樣做恐怕對於標題和本文的中文文題會顧此失彼了。

參考:1. 用utl_smtp發送郵件時的漢字解決方案

        2. 執行個體講解如何通過Oracle成功發送郵件

        3. 用oracle發送郵件(功能很全)
介紹了附件的發送
        4. Oracle UTL_SMTP

        5. 用telnet發郵件(支援smtp認證)

附註:在 Oracle(8.1.7及以上版本) 中可以用下面語句獲得字串的 base64 編碼,如:

select UTL_RAW.cast_to_varchar2(UTL_ENCODE.base64_encode(UTL_RAW.cast_to_raw('user'))) from dual;
select UTL_RAW.cast_to_varchar2(UTL_ENCODE.base64_encode(UTL_RAW.cast_to_raw('pass'))) from dual;

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.