Oracle 通过存储过程给关联者发信

CREATE OR REPLACE PROCEDURE sp_send_mail(
     p_recipient VARCHAR2, -- 邮件接收人 多个接收人 中间用分号隔开就可以
     p_subject   VARCHAR2, -- 邮件标题
     p_message   VARCHAR2  -- 邮件正文
)
IS

  --下面四个变量请根据实际邮件服务器进行赋值
 v_mailhost  VARCHAR2(300) := 'smtp.qq.com';     --SMTP服务器地址  
   v_user      VARCHAR2(300) := '123456@qq.com'; --登录SMTP服务器的用户名;只是用户名,不包括163.com部分
   v_pass      VARCHAR2(200) := '123456';  --登录SMTP服务器的密码
   v_sender    VARCHAR2(500)  := '123456@qq.com'; --发送都邮箱,一般与 ps_user 对应

   v_conn  UTL_SMTP.connection; --到邮件服务器的连接
   v_msg varchar2(4000);  --邮件内容
    
   TYPE ADDRESS_LIST IS TABLE OF VARCHAR2(100) INDEX BY BINARY_INTEGER;
  MY_ADDRESS_LIST ADDRESS_LIST;

  
    PROCEDURE P_SPLITE_STR(P_STR VARCHAR2, P_SPLITE_FLAG INT DEFAULT 1) IS
    L_ADDR VARCHAR2(254) := '';
    L_LEN  INT;
    L_STR  VARCHAR2(4000);
    J      INT := 0; --表示邮件地址或者附件的个数
  BEGIN
    /*处理接收邮件地址列表,包括去空格、将;转换为,等*/
    L_STR := TRIM(RTRIM(REPLACE(REPLACE(P_STR, ';', ','), ' ', ''), ','));
    L_LEN := LENGTH(L_STR);
    FOR I IN 1 .. L_LEN LOOP
      IF SUBSTR(L_STR, I, 1) <> ',' THEN
        L_ADDR := L_ADDR || SUBSTR(L_STR, I, 1);
      ELSE
        J := J + 1;
        IF P_SPLITE_FLAG = 1 THEN
          --表示处理邮件地址
          --前后需要加上'<>',否则很多邮箱将不能发送邮件
          L_ADDR := '<' || L_ADDR || '>';
          --调用邮件发送过程
          MY_ADDRESS_LIST(J) := L_ADDR;       
        END IF;
        L_ADDR := '';
      END IF;
      IF I = L_LEN THEN
        J := J + 1;
        IF P_SPLITE_FLAG = 1 THEN
          --调用邮件发送过程
          L_ADDR := '<' || L_ADDR || '>';
          MY_ADDRESS_LIST(J) := L_ADDR;        
        END IF;
      END IF;
    END LOOP;
  END;

 BEGIN
   
    P_SPLITE_STR(p_recipient);
 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.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 || '>');  --设置收件人 
      
       
       FOR K IN 1 .. MY_ADDRESS_LIST.COUNT LOOP
       --P_EMAIL(L_SENDORADDRESS, MY_ADDRESS_LIST(K));
        UTL_SMTP.rcpt(v_conn, MY_ADDRESS_LIST(K));
    END LOOP;
       -- RCPT TO 送信先 循环送信
     /* FOR idx IN p_to_list.FIRST .. p_to_list.LAST
      LOOP
        UTL_SMTP.RCPT(v_conn, '<' || p_to_list(idx).EMAIL || '>');
      END LOOP;*/
      --

      -- 创建要发送的邮件内容 注意报头信息和邮件正文之间要空一行
      v_msg :='Date:'|| TO_CHAR(SYSDATE, 'dd mon yy hh24:mi:ss')
         || UTL_TCP.CRLF || 'From: '|| v_sender || '<' || v_sender || '>'
        || UTL_TCP.CRLF || 'To: '  || p_recipient || '<' || p_recipient || '>'
         || UTL_TCP.CRLF || 'Subject: ' || p_subject
         || UTL_TCP.CRLF || UTL_TCP.CRLF  -- 这前面是报头信息
         || p_message;    -- 这个是邮件正文

      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); --关闭连接

 EXCEPTION

    WHEN OTHERS THEN
         DBMS_OUTPUT.put_line(DBMS_UTILITY.format_error_stack);
         DBMS_OUTPUT.put_line(DBMS_UTILITY.format_call_stack);

END sp_send_mail;

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值