Chinaunix首页 | 论坛 | 博客
  • 博客访问: 28894
  • 博文数量: 8
  • 博客积分: 10
  • 博客等级: 民兵
  • 技术积分: 10
  • 用 户 组: 普通用户
  • 注册时间: 2011-01-27 08:51
文章分类
文章存档

2014年(8)

我的朋友

分类: Oracle

2014-05-25 17:43:43


utl_mail 發送email當內容大於 32767時就無法處理,
所以寫了個plsql package ,利用clob發送.內容, 附檔用blob .

測試代碼1:

点击(此处)折叠或打开

  1. begin
  2.   pkg_mail.send_mail('test@163.com.cn','test@163.com.cn',
  3.      subject => '測試',
  4.      message => '測試email',
  5.     mime_type => 'text/plain; charset=big5'
  6.   ) ;
  7. end ;
測試代碼2

点击(此处)折叠或打开

  1. begin
  2.   pkg_mail.send_mail('test@163.com.cn','test@163.com.cn',
  3.   subject => '測試',
  4.   message => utl_lob.get_clob('MAILTEMP','jxxx_cc1.html'),
  5.   mime_type => 'text/html; charset=big5',
  6.   attachment=>utl_lob.get_blob('MAILTEMP','test.xls'),
  7.   att_filename=>'test.xls'
  8.   
  9.   ) ;
  10. end ;


email發送package

点击(此处)折叠或打开

  1. create or replace package PKG_MAIL is
  2. /****************************************
  3.    Ver Date Author Description
  4.    --------- ---------- --------------- ------------------------------------
  5.    1.0 2013-08-14 gangjh 1. pl/sql發送email
  6. *****************************************************************/
  7.   
  8.   type string_array is table of varchar2(200) ;

  9.   FUNCTION split_string (
  10.     p_str IN VARCHAR2,
  11.     p_delim IN VARCHAR2 default(';') --分隔符,默認分號
  12.  ) RETURN string_array pipelined ;



  13.   subtype handle is number ;
  14.   

  15.   function open_mail return number ;
  16.   /*
  17.   @set_attribute
  18.    id: 'from' mailfrom;
  19.        'to' mailto ;
  20.        'cc' ccto ;
  21.        'subject' subject ;
  22.   */
  23.   procedure set_attribute(ctx handle, id varchar, val varchar2) ;

  24.   procedure set_trans_info(p_smtphost varchar2, p_auth varchar2, p_pass varchar2);


  25.   PROCEDURE set_content(ctx handle, data IN CLOB, mime_type VARCHAR2);

  26.   PROCEDURE set_attach(ctx handle, data IN blob, filename VARCHAR2) ;

  27.   PROCEDURE send(ctx handle, vhost VARCHAR2, vport NUMBER DEFAULT 25, auth_login in varchar2 default null, auth_pass in varchar2 default null);

  28.   function get_MimeMessage(ctx in handle) return clob ;

  29.   PROCEDURE close_mail(ctx handle);
  30.  
  31.    PROCEDURE send_mail(
  32.                  sender IN VARCHAR2 ,
  33.                  recipients IN VARCHAR2 ,
  34.                  cc IN VARCHAR2 DEFAULT NULL,
  35.                  bcc IN VARCHAR2 DEFAULT NULL,
  36.                  subject IN VARCHAR2 DEFAULT NULL,
  37.                  message IN CLOB DEFAULT NULL,
  38.                  mime_type IN VARCHAR2 DEFAULT 'text/plain; charset=us-ascii',
  39.                  priority IN PLS_INTEGER DEFAULT 3,
  40.                  attachment IN BLOB default null,
  41.                  att_inline IN BOOLEAN DEFAULT TRUE,
  42.                  att_mime_type IN VARCHAR2 DEFAULT 'text/plain; charset=us-ascii',
  43.                  att_filename IN VARCHAR2 DEFAULT NULL) ;

  44. end PKG_MAIL;

  45.  
  46. /
  47. create or replace package body PKG_MAIL is
  48. /*
  49. +------------------------- multipart/mixed ----------------------------+
  50. | |
  51. | +----------------- multipart/related ------------------+ |
  52. | | | |
  53. | | +----- multipart/alternative ------+ +----------+ | +------+ |
  54. | | | | | 內嵌資源 | | | 附件 | |
  55. | | | +------------+ +------------+ | +----------+ | +------+ |
  56. | | | | 純文本正文 | | 超文本正文 | | | |
  57. | | | +------------+ +------------+ | +----------+ | +------+ |
  58. | | | | | 內嵌資源 | | | 附件 | |
  59. | | +----------------------------------+ +----------+ | +------+ |
  60. | | | |
  61. | +------------------------------------------------------+ |
  62. | |
  63. +----------------------------------------------------------------------+
  64. 可以看出,如果在郵件中要添加附件,必需定義multipart/mixed段;
  65.    如果存在內嵌資源,至少要定義multipart/related段;
  66.    如果純文本与超文本共存,至少要定義multipart/alternative段。
  67.       什么是“至少”???例子?,如果只有純文本与超文本正文,那么在郵件頭中將類型擴大化,定義為multipart/related,甚至multipart/mixed,都是允許的。

  68. multipart諸類型的共同特征是,
  69.   在段頭指定“boundary”參數字符串, 段体內的每個子段以此串定界。
  70.   所有的子段都以“--”+boundary行開始,
  71.     父段則以“--”+boundary+“--”行結束。
  72.      段与段之間也以空行分隔。
  73.      在郵件体是multipart類型的情況下,郵件体的開始部分(第一個“--”+boundary行之前)可以有一些附加的文本行,相當于注釋,解碼時應忽略。
  74.      段間也可以有一些附加的文本行,不會顯示出來,

  75. */
  76.  type mail_addr_rec is record(
  77.     address varchar2(200),
  78.     username varchar2(200),
  79.     enc_addr varchar2(200)
  80.     );
  81.   type mail_addr_t is table of mail_addr_rec index by pls_integer ;

  82.   TYPE mail_content_t IS RECORD(
  83.     data CLOB,
  84.     mime_type VARCHAR2(200),
  85.     filename VARCHAR2(200));
  86.   type attach_table is table of mail_content_t index by pls_integer ;

  87.   type mail_data_type is record(
  88.     v_subject varchar2(2000),
  89.     charset varchar2(20),
  90.     m_from mail_addr_rec,
  91.     m_to mail_addr_t,
  92.     m_cc mail_addr_t,
  93.     m_bcc mail_addr_t,
  94.     reply_to mail_addr_rec,
  95.     priority pls_integer,
  96.     m_body mail_content_t,
  97.     attach attach_table
  98.     );
  99.   type mail_table is table of mail_data_type ;


  100.  crlf CONSTANT char(1):= chr(10);
  101.  default_mail_host varchar2(200) ;
  102.  smtp_auth_user varchar2(200) ;
  103.  smtp_auth_pass varchar2(200) ;

  104. v_maillist mail_table := mail_table() ;

  105.  procedure print(m varchar2) is
  106.  begin
  107.    dbms_output.put_line(m) ;
  108.  end ;
  109.  
  110. --以分號切割string
  111. function split_string(p_str in varchar2,
  112.                       p_delim in varchar2 default(';'))
  113.          return string_array pipelined
  114. as
  115.   l_str long := p_str || p_delim;
  116.   l_n number;
  117. begin
  118.   loop
  119.     l_n := instr(l_str, p_delim);
  120.     exit when (nvl(l_n,0) = 0);
  121.     pipe row (ltrim(rtrim(substr(l_str,1,l_n-1))));
  122.     l_str := substr(l_str, l_n +1);
  123.   end loop;
  124.   return;
  125. end ;

  126.   function string_to_base64(s varchar2) return varchar2 is
  127.   begin
  128.     return utl_raw.cast_to_varchar2(utl_encode.base64_encode(utl_raw.cast_to_raw(s)));
  129.   end ;
  130.     
  131.   function blob_to_base64( src in blob) return clob is
  132.     --取 3 的倍數 因為如果需要按照64字符每行分行,所以需要是16的倍數,所以下面的長度必需為 48的倍數
  133.     dest CLOB ;
  134.     sizeB integer := 6144;
  135.     buffer raw(6144);
  136.     offset integer default 1;
  137.   begin
  138.     dbms_lob.createtemporary(dest, true, dbms_lob.call) ;
  139.     while offset <= dbms_lob.getlength(src) LOOP
  140.        dbms_lob.read(src, sizeB, offset, buffer);
  141.        offset := offset + sizeB;
  142.        dbms_lob.append(dest, to_clob(utl_raw.cast_to_varchar2(utl_encode.base64_encode(buffer))));
  143.     end loop;
  144.     return dest ;
  145.   END blob_to_base64;


  146.   function clob_to_base64( src IN CLOB ) return clob IS
  147.     v_blob blob;
  148.     v_blob_offset int :=1;
  149.     v_clob_offset int :=1 ;
  150.     v_lang_context NUMBER := DBMS_LOB.DEFAULT_LANG_CTX;
  151.     v_warning integer ;
  152.   BEGIN
  153.     IF src IS NULL THEN
  154.       RETURN null;
  155.     END IF ;
  156.     dbms_lob.createtemporary(v_blob, true, dbms_lob.call) ;

  157.     dbms_lob.converttoblob(v_blob,
  158.                           src,
  159.                           dbms_lob.getlength(src),
  160.                           v_blob_offset,
  161.                           v_clob_offset,
  162.                           dbms_lob.default_csid ,
  163.                           v_lang_context,
  164.                           v_warning);
  165.     return blob_to_base64(v_blob) ;
  166.   END ;

  167.  procedure write_line(l in out nocopy clob , msg varchar2) is
  168.  begin
  169.     if length(msg) >0 then
  170.         dbms_lob.writeappend(l, length(msg), msg) ;
  171.     end if ;
  172.     dbms_lob.writeappend(l, 1, crlf) ;
  173.  end write_line;

  174. --第2行需要有前置空格
  175.  FUNCTION encstr(m VARCHAR2) RETURN VARCHAR2 IS
  176.  BEGIN
  177.     return replace( utl_encode.mimeheader_encode(m, null, 1),chr(10), chr(10)||chr(9) ) ;
  178. -- RETURN '=?utf-8?B?'|| replace(string_to_base64(m), chr(10), chr(10)||chr(9))||'?=' ;
  179.  END ;
  180.  
  181. /********************
  182. 發件時間:固定格式
  183. ex:
  184. Date: Wed, 20 Nov 2013 14:13:06 +0800
  185. ********************/
  186.  function get_datestr return varchar2 is
  187.  begin
  188.    return TO_CHAR(SYSDATE,'Dy, dd Mon yyyy hh24:mi:ss ', 'NLS_DATE_LANGUAGE = American')||
  189.                    replace(sessiontimezone,':','') ;
  190.  end ;


  191.   /* ---begin parase address
  192.   @escape_address -- 解析 email address
  193.    mail_alias 或mail-address
  194.   分拆開來
  195.   p_addr.address :=
  196.   p_addr.username := user alias
  197.   *********/
  198.  procedure escape_address(p_to in varchar2, p_addr in out mail_addr_rec) is
  199.    i int ;
  200.    v_to varchar2(32760) := trim(replace(replace(p_to, chr(10),''), chr(13),'')) ;
  201.    begin
  202.     i := instr(v_to,'<') ;
  203.     if i >0 then
  204.       p_addr.username := trim(substr(v_to, 1, i-1)) ;
  205.       p_addr.address := trim(substr(v_to, i)) ;
  206.     else
  207.       p_addr.address := '<'|| v_to ||'>' ;
  208.       p_addr.username := substr(v_to, 1, instr(v_to, '@')-1) ;
  209.     end if;
  210.     
  211.     p_addr.enc_addr :=
  212.         case
  213.         when p_addr.username is null then p_addr.address
  214.         else encstr(p_addr.username) ||p_addr.address
  215.         end ;
  216.    end ;

  217.    procedure parser_address(v_to in varchar2 , out_addr in out mail_addr_t ) is
  218.      idx int ;
  219.      aa mail_addr_rec ;
  220.    begin
  221.      if v_to is null or length(v_to) =0 then
  222.        return ;
  223.      end if ;
  224.        
  225.      for r in (select trim(column_value) data from table(split_string(replace(v_to,',',';'), ';'))
  226.          where length(trim(column_value)) >5
  227.         )
  228.      loop
  229.          idx := out_addr.count + 1 ;
  230.          escape_address(trim(r.data), aa) ;
  231.          out_addr(idx) := aa ;
  232.      end loop;
  233.   end parser_address;

  234. /****************
  235. @addr_to_str -- 將收件者數組轉為編碼後的字串
  236.    第2個mail_address前需有空格
  237. *****************/
  238.    function addr_to_str(v mail_addr_t, p_delim in varchar2 default chr(9)) return varchar2 is
  239.    tmp varchar2(32767) ;
  240.    begin
  241.      if v.count <=0 then
  242.        return null;
  243.      end if;

  244.      for i in v.first .. v.last loop
  245.       if v.exists(i) then
  246.           tmp := tmp || p_delim || v(i).enc_addr ||','||crlf ;
  247.       end if;
  248.     end loop ;
  249.     -- "," +crlf size=2
  250.     return substr(tmp, 1, length(tmp)-2) ;
  251.    end addr_to_str;

  252.  function open_mail return number is
  253.    x number ;
  254.    d mail_data_type ;
  255.  BEGIN
  256.    v_maillist.extend() ;
  257.    x := v_maillist.last() ;
  258.    v_maillist(x) := d;
  259.    return x ;
  260.  END open_mail;




  261.  procedure set_attribute(ctx handle, id varchar, val varchar2) is
  262.    x varchar2(20) := lower(id) ;
  263.  begin
  264.    case
  265.      when x = 'from' then escape_address(val, v_maillist(ctx).m_from ) ;
  266.      when x = 'to' then parser_address(val, v_maillist(ctx).m_to ) ;
  267.      when x = 'cc' then parser_address(val, v_maillist(ctx).m_cc) ;
  268.      when x = 'bcc' then parser_address(val, v_maillist(ctx).m_bcc) ;
  269.      when x = 'reply-to' then escape_address(val, v_maillist(ctx).reply_to) ;
  270.      when x = 'priority' then v_maillist(ctx).priority := val ;
  271.      when x = 'subject' then v_maillist(ctx).v_subject := val ;
  272.      when x = 'charset' then v_maillist(ctx).charset := val ;
  273.      
  274.    else
  275.      raise_application_error(-20013, '不支持參數 [ '||id||' ]') ;
  276.    end case ;

  277.  end ;
  278.  
  279.  procedure set_trans_info(p_smtphost varchar2, p_auth varchar2, p_pass varchar2) is
  280.  begin
  281.    default_mail_host := p_smtphost;
  282.    smtp_auth_user := p_auth ;
  283.    smtp_auth_pass := p_pass;
  284.  end ;
  285.    


  286.  PROCEDURE set_content(ctx handle ,data IN CLOB , mime_type VARCHAR2 ) IS
  287.  BEGIN
  288.    v_maillist(ctx).m_body.data := clob_to_base64(data) ;
  289.    v_maillist(ctx).m_body.mime_type := mime_type ;
  290.  END ;

  291.  PROCEDURE set_attach(ctx handle, data IN blob, filename VARCHAR2 ) IS
  292.  idx pls_integer ;
  293.  BEGIN
  294.     idx := v_maillist(ctx).attach.count() +1;
  295.     v_maillist(ctx).attach(idx).filename := filename ;
  296.     v_maillist(ctx).attach(idx).data := blob_to_base64(data) ;
  297.  END ;



  298.  /********************
  299.   multipart/mixed
  300.        multipart/alternative;
  301.  將email編碼內容寫入blob
  302. *************************/
  303.  procedure mime_mail_multipart(lob_loc in out nocopy clob, m in mail_data_type ) is
  304.    mail_bonndary1 CONSTANT VARCHAR2(200) :='----=_Part_1_922723413.1367658258997';


  305.    procedure set_header(n in varchar2 ,v in varchar2) is
  306.    begin
  307.      write_line(lob_loc, n ||': '||v ) ;
  308.    end set_header;

  309.    PROCEDURE write_header IS
  310.    BEGIN

  311.   /*Reply-to: 回復地址 */
  312.     if m.reply_to.address is not null then
  313.        set_header('Reply-To', m.reply_to.enc_addr );
  314.     end if;
  315.     set_header('From', m.m_from.enc_addr );
  316.     set_header('To', addr_to_str(m.m_to ) );

  317.     if m.m_cc.count >0 then
  318.       set_header('CC', addr_to_str(m.m_cc) );
  319.     end if;

  320.     set_header('Subject', encstr(m.v_subject) );
  321.      
  322.     set_header('MIME-Version','1.0');
  323.     
  324.     set_header('Content-Type','multipart/mixed;
  325.         boundary="'|| mail_bonndary1 ||'"');

  326. -- set_header(l, 'Content-Language', v_mail_charset ) ;
  327.     set_header('X-Priority', nvl(m.priority,3));

  328.     set_header('Date', get_datestr() ) ;
  329.     set_header('X-MSMail-Priority','Normal');
  330.     set_header('X-Mailer','Microsoft Outlook Express 6.00.2900.5931');
  331.     set_header('X-MimeOLE','Produced By Microsoft MimeOLE V6.00.2900.6157');

  332.     write_line(lob_loc, '') ;
  333.     write_line(lob_loc, 'This is a multi-part message in MIME format.') ;
  334.     write_line(lob_loc, dbms_utility.format_call_stack) ;
  335.     write_line(lob_loc, crlf||crlf );


  336.  END write_header;


  337.  PROCEDURE write_mail_body(bonndary varchar2 ) IS
  338.     mail_bonndary2 CONSTANT VARCHAR2(200) :='----=_Part_2_922723413.136765825899X';
  339.  BEGIN
  340.   /* multipart/alternative */
  341.     write_line(lob_loc, '--'||bonndary ) ;

  342.     set_header('Content-Type', 'multipart/alternative;
  343.       boundary="'||mail_bonndary2 ||'"') ;
  344.     write_line(lob_loc, '') ; -- 空行
  345.         
  346.     write_line(lob_loc, '--'||mail_bonndary2 ) ;
  347.     set_header('Content-Type', m.m_body.mime_type );
  348.     set_header('Content-Transfer-Encoding','base64');
  349.     write_line(lob_loc, crlf);

  350.     dbms_lob.append(lob_loc, m.m_body.data);

  351.     write_line(lob_loc,'') ;
  352.     write_line(lob_loc, '--'||mail_bonndary2 ||'--') ;
  353.     write_line(lob_loc, '') ;
  354.  END write_mail_body;


  355.  PROCEDURE write_mail_attach(attach mail_content_t, bonndary varchar2 ) IS
  356.  BEGIN
  357.     if attach.data is null or dbms_lob.getlength(attach.data ) <=0
  358.     then
  359.       return ;
  360.     end if;

  361.     write_line(lob_loc, '--'||bonndary ) ;
  362.     set_header('Content-Transfer-Encoding', 'base64');
  363.     set_header('Content-Disposition', 'attachment;
  364.       filename="'||encstr( attach.filename )||'"') ;

  365.     write_line(lob_loc, crlf) ;

  366.     dbms_lob.append(lob_loc, attach.data);
  367.     
  368.     write_line(lob_loc, crlf);
  369.  END write_mail_attach;

  370.    begin
  371.  -- set_header(lob_loc, 'In-Reply-To','');

  372.    
  373.     write_header() ;

  374.     write_mail_body(mail_bonndary1) ;
  375.     for i in 1.. m.attach.count() loop
  376.         write_mail_attach(m.attach(i) , mail_bonndary1) ;
  377.     end loop;

  378.    --end send mailbody data
  379.     write_line(lob_loc, '--'||mail_bonndary1 || '--') ;

  380.    end mime_mail_multipart;


  381.  function get_MimeMessage(ctx in handle) return clob
  382.  is
  383.    clob_loc clob;
  384.  begin
  385.     dbms_lob.createtemporary(clob_loc, true, dbms_lob.call) ;
  386.     mime_mail_multipart(clob_loc, v_maillist(ctx) );
  387.     return clob_loc ;
  388.  end ;


  389.    procedure smtp_send_content(l IN OUT NOCOPY utl_smtp.connection, lob_loc in out nocopy clob) is
  390.    offset number := 1;
  391.    lc_buffer varchar2(32767);
  392.    amount number := 30000 ;
  393.    begin
  394.       while offset <= dbms_lob.getlength(lob_loc) LOOP
  395.         dbms_lob.read(lob_loc, amount , offset, lc_buffer) ;
  396.         offset := offset + amount ;
  397.         utl_smtp.write_raw_data(l, utl_raw.cast_to_raw(lc_buffer)) ;
  398.     end loop;
  399.     utl_smtp.write_data(l, crlf);
  400.        
  401.  end smtp_send_content;


  402.  procedure smtp_auth(l in out nocopy utl_smtp.connection ,username varchar2 , password varchar2) is
  403.  begin
  404.     if username is null or password is null then
  405.       return ;
  406.     end if ;
  407.     
  408.     utl_smtp.command(l, 'AUTH LOGIN');
  409.     utl_smtp.command(l, string_to_base64(username)) ;
  410.     utl_smtp.command(l, string_to_base64(password)) ;
  411.  end smtp_auth;
  412.  
  413. --指明email收件者
  414.  PROCEDURE smtp_rcpt(l in out nocopy utl_smtp.connection, addr mail_addr_t ) IS
  415.  begin
  416.     if addr.count() <=0 then
  417.        return ;
  418.     end if ;
  419.     
  420.     for i in addr.first .. addr.last loop
  421.       begin
  422.         utl_smtp.rcpt(l, addr(i).address);
  423.       exception
  424.         when utl_smtp.permanent_error then
  425.           print(dbms_utility.format_call_stack||' deny:'||addr(i).address) ;
  426.           raise_application_error(-20014,' deny:'||addr(i).address||chr(10)||sqlerrm);
  427.       end ;
  428.     end loop;
  429.  end smtp_rcpt;

  430.  PROCEDURE send(ctx handle, vhost VARCHAR2, vport NUMBER DEFAULT 25, auth_login in varchar2 default null, auth_pass in varchar2 default null ) IS
  431.    l_conn utl_smtp.connection ;
  432.    msg clob ;
  433.    m mail_data_type ;
  434.  BEGIN
  435.     m := v_maillist(ctx) ;
  436.     
  437.     dbms_lob.createtemporary(msg, true, dbms_lob.call);
  438.     mime_mail_multipart(msg, m) ;
  439.     if m.m_to.count()<1 then
  440.       raise_application_error(-20013,'收件者不能為空') ;
  441.     end if;
  442.         
  443.     l_conn := utl_smtp.open_connection(vhost, vport, tx_timeout=>15) ;
  444.     
  445.     utl_smtp.helo(l_conn, vhost);
  446.     
  447.     smtp_auth(l_conn, auth_login, auth_pass) ;
  448.     
  449.     utl_smtp.mail(l_conn, m.m_from.address) ;
  450.     smtp_rcpt(l_conn, m.m_to) ;
  451.     smtp_rcpt(l_conn, m.m_cc) ;
  452.     smtp_rcpt(l_conn, m.m_bcc) ; --秘件收件者
  453.     
  454.     utl_smtp.open_data(l_conn);
  455.     smtp_send_content(l_conn, msg);
  456.     utl_smtp.close_data(l_conn);
  457.     
  458.     utl_smtp.quit(l_conn);

  459.     dbms_lob.freetemporary(msg) ;
  460.     exception
  461.       when utl_smtp.permanent_error or utl_smtp.invalid_operation then
  462.         utl_smtp.quit(l_conn);
  463.         raise;
  464.       when others then
  465.           raise;
  466.  END send ;


  467.  PROCEDURE close_mail(ctx handle) IS
  468.  BEGIN
  469.     v_maillist.delete(ctx) ;
  470.     v_maillist.trim() ;
  471.  END ;
  472.  
  473.  
  474.  --parameter keep same as utl_mail.send_attach_varchar2
  475.  PROCEDURE send_mail(
  476.                  sender IN VARCHAR2 ,
  477.                  recipients IN VARCHAR2 ,
  478.                  cc IN VARCHAR2 DEFAULT NULL,
  479.                  bcc IN VARCHAR2 DEFAULT NULL,
  480.                  subject IN VARCHAR2 DEFAULT NULL,
  481.                  message IN CLOB DEFAULT NULL,
  482.                  mime_type IN VARCHAR2 DEFAULT 'text/plain; charset=us-ascii',
  483.                  priority IN PLS_INTEGER DEFAULT 3,
  484.                  attachment IN BLOB default null,
  485.                  att_inline IN BOOLEAN DEFAULT TRUE,
  486.                  att_mime_type IN VARCHAR2 DEFAULT 'text/plain; charset=us-ascii',
  487.                  att_filename IN VARCHAR2 DEFAULT NULL) is
  488.     ctx pkg_mail.handle ;
  489.   BEGIN
  490.      ctx := pkg_mail.open_mail() ;
  491.      set_attribute(ctx, 'from', sender) ;
  492.      set_attribute(ctx, 'to', recipients) ;
  493.      set_attribute(ctx, 'cc', cc) ;
  494.      set_attribute(ctx, 'bcc', bcc) ;
  495.      set_attribute(ctx, 'subject', subject) ;
  496.      set_attribute(ctx, 'priority', priority) ;

  497.      set_content(ctx, message, mime_type) ;

  498.      if length(att_filename) >0 and attachment is not null then
  499.        set_attach(ctx, attachment, att_filename ) ;
  500.      end if;

  501.      send(ctx, default_mail_host, 25, smtp_auth_user, smtp_auth_pass);
  502.      close_mail(ctx) ;
  503. end ;
  504.  
  505. begin

  506. declare
  507.  xx binary_integer ;
  508.  ff binary_integer ;
  509. begin
  510.  xx := sys.dbms_utility.get_parameter_value(parnam => 'smtp_out_server',
  511.                                             intval => ff,
  512.                                             strval => default_mail_host,
  513.                                             listno => 1);
  514. end ;

  515. end PKG_MAIL;
  516. /




 2014/03/08修改

阿飛

阅读(2215) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~