天天看点

Oracle 存储过程发送邮件

<code>CREATE</code> <code>OR</code> <code>REPLACE</code> <code>PROCEDURE</code> <code>PROCSENDEMAIL(P_TXT       VARCHAR2,</code>

<code>                                          </code><code>P_SUB       VARCHAR2,</code>

<code>                                          </code><code>P_SENDOR    VARCHAR2,</code>

<code>                                          </code><code>P_RECEIVER  VARCHAR2,</code>

<code>                                          </code><code>P_SERVER    VARCHAR2,</code>

<code>                                          </code><code>P_PORT      NUMBER</code><code>DEFAULT</code> <code>25,</code>

<code>                                          </code><code>P_NEED_SMTP</code><code>INT</code> <code>DEFAULT</code> <code>0,</code>

<code>                                          </code><code>P_USER      VARCHAR2</code><code>DEFAULT</code> <code>NULL</code><code>,</code>

<code>                                          </code><code>P_PASS      VARCHAR2</code><code>DEFAULT</code> <code>NULL</code><code>,</code>

<code>                                          </code><code>P_FILENAME  VARCHAR2</code><code>DEFAULT</code> <code>NULL</code><code>,</code>

<code>                                          </code><code>P_ENCODE    VARCHAR2</code><code>DEFAULT</code> <code>'bit 7'</code><code>)</code>

<code>  </code><code>AUTHID</code><code>CURRENT_USER</code> <code>IS</code>

<code>  </code><code>/*</code>

<code>  </code><code>作用:用oracle发送邮件</code>

<code>  </code><code>主要功能:1、支持多收件人。</code>

<code>            </code><code>2、支持中文</code>

<code>            </code><code>3、支持抄送人</code>

<code>            </code><code>4、支持大于32K的附件</code>

<code>            </code><code>5、支持多行正文</code>

<code>            </code><code>6、支持多附件</code>

<code>            </code><code>7、支持文本附件和二进制附件</code>

<code>            </code><code>8、支持HTML格式</code>

<code>            </code><code>8、支持</code>

<code>  </code><code>作者:suk</code>

<code>  </code><code>参数说明:</code>

<code>            </code><code>p_txt :邮件正文</code>

<code>            </code><code>p_sub: 邮件标题</code>

<code>            </code><code>p_SendorAddress : 发送人邮件地址</code>

<code>            </code><code>p_ReceiverAddress : 接收地址,可以同时发送到多个地址上,地址之间用","或者";"隔开</code>

<code>            </code><code>p_EmailServer : 邮件服务器地址,可以是域名或者IP</code>

<code>            </code><code>p_Port :邮件服务器端口</code>

<code>            </code><code>p_need_smtp:是否需要smtp认证,0表示不需要,1表示需要</code>

<code>            </code><code>p_user:smtp验证需要的用户名</code>

<code>            </code><code>p_pass:smtp验证需要的密码</code>

<code>            </code><code>p_filename:附件名称,必须包含完整的路径,如"d:tempa.txt"。</code>

<code>                        </code><code>可以有多个附件,附件名称只见用逗号或者分号分隔</code>

<code>            </code><code>p_encode:附件编码转换格式,其中 p_encode='bit 7' 表示文本类型附件</code>

<code>                                             </code><code>p_encode='base64' 表示二进制类型附件</code>

<code>  </code><code>注意:</code>

<code>        </code><code>1、对于文本类型的附件,不能用base64的方式发送,否则出错</code>

<code>        </code><code>2、对于多个附件只能用同一种格式发送</code>

<code>  </code><code>*/</code>

<code>  </code><code>L_CRLF          VARCHAR2(2) := UTL_TCP.CRLF;</code>

<code>  </code><code>L_SENDORADDRESS VARCHAR2(4000);</code>

<code>  </code><code>L_SPLITE        VARCHAR2(10) :=</code><code>'++'</code><code>;</code>

<code>  </code><code>BOUNDARY            CONSTANT VARCHAR2(256) :=</code><code>'-----BYSUK'</code><code>;</code>

<code>  </code><code>FIRST_BOUNDARY      CONSTANT VARCHAR2(256) :=</code><code>'--'</code> <code>|| BOUNDARY || L_CRLF;</code>

<code>  </code><code>LAST_BOUNDARY       CONSTANT VARCHAR2(256) :=</code><code>'--'</code> <code>|| BOUNDARY ||</code><code>'--'</code> <code>||</code>

<code>                                                </code><code>L_CRLF;</code>

<code>  </code><code>MULTIPART_MIME_TYPE CONSTANT VARCHAR2(256) :=</code><code>'multipart/mixed; boundary="'</code> <code>||</code>

<code>                                                </code><code>BOUNDARY ||</code><code>'"'</code><code>;</code>

<code>  </code><code>/* 以下部分是发送大二进制附件时用到的变量 */</code>

<code>  </code><code>L_FIL                 BFILE;</code>

<code>  </code><code>L_FILE_LEN            NUMBER;</code>

<code>  </code><code>L_MODULO              NUMBER;</code>

<code>  </code><code>L_PIECES              NUMBER;</code>

<code>  </code><code>L_FILE_HANDLE         UTL_FILE.FILE_TYPE;</code>

<code>  </code><code>L_AMT                 BINARY_INTEGER := 672 * 3;</code><code>/* ensures proper format;   2016 */</code>

<code>  </code><code>L_FILEPOS             PLS_INTEGER := 1;</code><code>/* pointer for the file */</code>

<code>  </code><code>L_CHUNKS              NUMBER;</code>

<code>  </code><code>L_BUF                 RAW(2100);</code>

<code>  </code><code>L_DATA                RAW(2100);</code>

<code>  </code><code>L_MAX_LINE_WIDTH      NUMBER := 54;</code>

<code>  </code><code>L_DIRECTORY_BASE_NAME VARCHAR2(100) :=</code><code>'DIR_FOR_SEND_MAIL'</code><code>;</code>

<code>  </code><code>L_LINE                VARCHAR2(1000);</code>

<code>  </code><code>L_MESG                VARCHAR2(32767);</code>

<code>  </code><code>/* 以上部分是发送大二进制附件时用到的变量 */</code>

<code>  </code><code>TYPE ADDRESS_LIST</code><code>IS</code> <code>TABLE</code> <code>OF</code> <code>VARCHAR2(100)</code><code>INDEX</code> <code>BY</code> <code>BINARY_INTEGER;</code>

<code>  </code><code>MY_ADDRESS_LIST ADDRESS_LIST;</code>

<code>  </code><code>TYPE ACCT_LIST</code><code>IS</code> <code>TABLE</code> <code>OF</code> <code>VARCHAR2(100)</code><code>INDEX</code> <code>BY</code> <code>BINARY_INTEGER;</code>

<code>  </code><code>MY_ACCT_LIST ACCT_LIST;</code>

<code>  </code><code>-------------------------------------返回附件源文件所在目录或者名称--------------------------------------</code>

<code>  </code><code>FUNCTION</code> <code>GET_FILE(P_FILE VARCHAR2, P_GET</code><code>INT</code><code>)</code><code>RETURN</code> <code>VARCHAR2</code><code>IS</code>

<code>    </code><code>--p_get=1 表示返回目录</code>

<code>    </code><code>--p_get=2 表示返回文件名</code>

<code>    </code><code>L_FILE VARCHAR2(1000);</code>

<code>  </code><code>BEGIN</code>

<code>    </code><code>IF INSTR(P_FILE,</code><code>''</code><code>) &gt; 0</code><code>THEN</code>

<code>      </code><code>--windows</code>

<code>      </code><code>IF P_GET = 1</code><code>THEN</code>

<code>        </code><code>L_FILE := SUBSTR(P_FILE, 1, INSTR(P_FILE,</code><code>''</code><code>, -1) - 1);</code>

<code>      </code><code>ELSIF P_GET = 2</code><code>THEN</code>

<code>        </code><code>L_FILE := SUBSTR(P_FILE, - (LENGTH(P_FILE) - INSTR(P_FILE,</code><code>''</code><code>, -1)));</code>

<code>      </code><code>END</code> <code>IF;</code>

<code>    </code><code>ELSIF INSTR(P_FILE,</code><code>'/'</code><code>) &gt; 0</code><code>THEN</code>

<code>      </code><code>--linux/unix</code>

<code>        </code><code>L_FILE := SUBSTR(P_FILE, 1, INSTR(P_FILE,</code><code>'/'</code><code>, -1) - 1);</code>

<code>        </code><code>L_FILE := SUBSTR(P_FILE,</code>

<code>                         </code><code>- (LENGTH(P_FILE) - INSTR(P_FILE,</code><code>'/'</code><code>, -1)));</code>

<code>    </code><code>END</code> <code>IF;</code>

<code>    </code><code>RETURN</code> <code>L_FILE;</code>

<code>  </code><code>END</code><code>;</code>

<code>  </code><code>---------------------------------------------删除directory------------------------------------</code>

<code>  </code><code>PROCEDURE</code> <code>DROP_DIRECTORY(P_DIRECTORY_NAME VARCHAR2)</code><code>IS</code>

<code>    </code><code>EXECUTE</code> <code>IMMEDIATE</code><code>'drop directory '</code> <code>|| P_DIRECTORY_NAME;</code>

<code>  </code><code>EXCEPTION</code>

<code>    </code><code>WHEN</code> <code>OTHERS</code><code>THEN</code>

<code>      </code><code>NULL</code><code>;</code>

<code>  </code><code>--------------------------------------------------创建directory-----------------------------------------</code>

<code>  </code><code>PROCEDURE</code> <code>CREATE_DIRECTORY(P_DIRECTORY_NAME VARCHAR2, P_DIR VARCHAR2)</code><code>IS</code>

<code>    </code><code>EXECUTE</code> <code>IMMEDIATE</code><code>'create directory '</code> <code>|| P_DIRECTORY_NAME ||</code><code>' as '</code><code>''</code> <code>||</code>

<code>                      </code><code>P_DIR ||</code><code>''</code><code>''</code><code>;</code>

<code>    </code><code>EXECUTE</code> <code>IMMEDIATE</code><code>'grant read,write on directory '</code> <code>|| P_DIRECTORY_NAME ||</code>

<code>                      </code><code>' to public'</code><code>;</code>

<code>      </code><code>RAISE;</code>

<code>  </code><code>--------------------------------------------分割邮件地址或者附件地址-----------------------------------</code>

<code>  </code><code>PROCEDURE</code> <code>P_SPLITE_STR(P_STR VARCHAR2, P_SPLITE_FLAG</code><code>INT</code> <code>DEFAULT</code> <code>1)</code><code>IS</code>

<code>    </code><code>L_ADDR VARCHAR2(254) :=</code><code>''</code><code>;</code>

<code>    </code><code>L_LEN </code><code>INT</code><code>;</code>

<code>    </code><code>L_STR  VARCHAR2(4000);</code>

<code>    </code><code>J     </code><code>INT</code> <code>:= 0;</code><code>--表示邮件地址或者附件的个数</code>

<code>    </code><code>/*处理接收邮件地址列表,包括去空格、将;转换为,等*/</code>

<code>    </code><code>L_STR := TRIM(RTRIM(</code><code>REPLACE</code><code>(</code><code>REPLACE</code><code>(P_STR,</code><code>';'</code><code>,</code><code>','</code><code>),</code><code>' '</code><code>,</code><code>''</code><code>),</code><code>','</code><code>));</code>

<code>    </code><code>L_LEN := LENGTH(L_STR);</code>

<code>    </code><code>FOR</code> <code>I</code><code>IN</code> <code>1 .. L_LEN LOOP</code>

<code>      </code><code>IF SUBSTR(L_STR, I, 1) &lt;&gt;</code><code>','</code> <code>THEN</code>

<code>        </code><code>L_ADDR := L_ADDR || SUBSTR(L_STR, I, 1);</code>

<code>      </code><code>ELSE</code>

<code>        </code><code>J := J + 1;</code>

<code>        </code><code>IF P_SPLITE_FLAG = 1</code><code>THEN</code>

<code>          </code><code>--表示处理邮件地址</code>

<code>          </code><code>--前后需要加上'&lt;&gt;',否则很多邮箱将不能发送邮件</code>

<code>          </code><code>L_ADDR :=</code><code>'&lt;'</code> <code>|| L_ADDR ||</code><code>'&gt;'</code><code>;</code>

<code>          </code><code>--调用邮件发送过程</code>

<code>          </code><code>MY_ADDRESS_LIST(J) := L_ADDR;</code>

<code>        </code><code>ELSIF P_SPLITE_FLAG = 2</code><code>THEN</code>

<code>          </code><code>--表示处理附件名称</code>

<code>          </code><code>MY_ACCT_LIST(J) := L_ADDR;</code>

<code>        </code><code>END</code> <code>IF;</code>

<code>        </code><code>L_ADDR :=</code><code>''</code><code>;</code>

<code>      </code><code>IF I = L_LEN</code><code>THEN</code>

<code>    </code><code>END</code> <code>LOOP;</code>

<code>  </code><code>------------------------------------------------写邮件头和邮件内容------------------------------------------</code>

<code>  </code><code>PROCEDURE</code> <code>WRITE_DATA(P_CONN  </code><code>IN</code> <code>OUT</code> <code>NOCOPY UTL_SMTP.</code><code>CONNECTION</code><code>,</code>

<code>                       </code><code>P_NAME  </code><code>IN</code> <code>VARCHAR2,</code>

<code>                       </code><code>P_VALUE </code><code>IN</code> <code>VARCHAR2,</code>

<code>                       </code><code>P_SPLITE VARCHAR2</code><code>DEFAULT</code> <code>':'</code><code>,</code>

<code>                       </code><code>P_CRLF   VARCHAR2</code><code>DEFAULT</code> <code>L_CRLF)</code><code>IS</code>

<code>    </code><code>/* utl_raw.cast_to_raw 对解决中文乱码问题很重要*/</code>

<code>    </code><code>UTL_SMTP.WRITE_RAW_DATA(P_CONN,</code>

<code>                            </code><code>UTL_RAW.CAST_TO_RAW(</code><code>CONVERT</code><code>(P_NAME || P_SPLITE ||</code>

<code>                                                        </code><code>P_VALUE || P_CRLF,</code>

<code>                                                        </code><code>'ZHS16GBK'</code><code>)));</code>

<code>  </code><code>----------------------------------------写MIME邮件尾部-----------------------------------------------------</code>

<code>  </code><code>PROCEDURE</code> <code>END_BOUNDARY(CONN</code><code>IN</code> <code>OUT</code> <code>NOCOPY UTL_SMTP.</code><code>CONNECTION</code><code>,</code>

<code>                         </code><code>LAST</code> <code>IN</code> <code>BOOLEAN</code><code>DEFAULT</code> <code>FALSE</code><code>)</code><code>IS</code>

<code>    </code><code>UTL_SMTP.WRITE_DATA(CONN, UTL_TCP.CRLF);</code>

<code>    </code><code>IF (</code><code>LAST</code><code>)</code><code>THEN</code>

<code>      </code><code>UTL_SMTP.WRITE_DATA(CONN, LAST_BOUNDARY);</code>

<code>  </code><code>----------------------------------------------发送附件----------------------------------------------------</code>

<code>  </code><code>PROCEDURE</code> <code>ATTACHMENT(CONN        </code><code>IN</code> <code>OUT</code> <code>NOCOPY UTL_SMTP.</code><code>CONNECTION</code><code>,</code>

<code>                       </code><code>MIME_TYPE   </code><code>IN</code> <code>VARCHAR2</code><code>DEFAULT</code> <code>'text/plain'</code><code>,</code>

<code>                       </code><code>INLINE      </code><code>IN</code> <code>BOOLEAN</code><code>DEFAULT</code> <code>TRUE</code><code>,</code>

<code>                       </code><code>FILENAME    </code><code>IN</code> <code>VARCHAR2</code><code>DEFAULT</code> <code>'t.txt'</code><code>,</code>

<code>                       </code><code>TRANSFER_ENC</code><code>IN</code> <code>VARCHAR2</code><code>DEFAULT</code> <code>'7 bit'</code><code>,</code>

<code>                       </code><code>DT_NAME     </code><code>IN</code> <code>VARCHAR2</code><code>DEFAULT</code> <code>'0'</code><code>)</code><code>IS</code>

<code>    </code><code>L_FILENAME VARCHAR2(1000);</code>

<code>    </code><code>--写附件头</code>

<code>    </code><code>UTL_SMTP.WRITE_DATA(CONN, FIRST_BOUNDARY);</code>

<code>    </code><code>--设置附件格式</code>

<code>    </code><code>WRITE_DATA(CONN,</code><code>'Content-Type'</code><code>, MIME_TYPE);</code>

<code>    </code><code>--如果文件名称非空,表示有附件</code>

<code>    </code><code>DROP_DIRECTORY(DT_NAME);</code>

<code>    </code><code>--创建directory</code>

<code>    </code><code>CREATE_DIRECTORY(DT_NAME, GET_FILE(FILENAME, 1));</code>

<code>    </code><code>--得到附件文件名称</code>

<code>    </code><code>L_FILENAME := GET_FILE(FILENAME, 2);</code>

<code>    </code><code>IF (INLINE)</code><code>THEN</code>

<code>      </code><code>WRITE_DATA(CONN,</code>

<code>                 </code><code>'Content-Disposition'</code><code>,</code>

<code>                 </code><code>'inline; filename="'</code> <code>|| L_FILENAME ||</code><code>'"'</code><code>);</code>

<code>    </code><code>ELSE</code>

<code>                 </code><code>'attachment; filename="'</code> <code>|| L_FILENAME ||</code><code>'"'</code><code>);</code>

<code>    </code><code>--设置附件的转换格式</code>

<code>    </code><code>IF (TRANSFER_ENC</code><code>IS</code> <code>NOT</code> <code>NULL</code><code>)</code><code>THEN</code>

<code>      </code><code>WRITE_DATA(CONN,</code><code>'Content-Transfer-Encoding'</code><code>, TRANSFER_ENC);</code>

<code>    </code><code>--begin 贴附件内容</code>

<code>    </code><code>IF TRANSFER_ENC =</code><code>'bit 7'</code> <code>THEN</code>

<code>      </code><code>--如果是文本类型的附件</code>

<code>      </code><code>BEGIN</code>

<code>        </code><code>L_FILE_HANDLE := UTL_FILE.FOPEN(DT_NAME, L_FILENAME,</code><code>'r'</code><code>);</code><code>--打开文件</code>

<code>        </code><code>--把附件分成多份,这样可以发送超过32K的附件</code>

<code>        </code><code>LOOP</code>

<code>          </code><code>UTL_FILE.GET_LINE(L_FILE_HANDLE, L_LINE);</code>

<code>          </code><code>L_MESG := L_LINE || L_CRLF;</code>

<code>          </code><code>WRITE_DATA(CONN,</code><code>''</code><code>, L_MESG,</code><code>''</code><code>,</code><code>''</code><code>);</code>

<code>        </code><code>END</code> <code>LOOP;</code>

<code>        </code><code>UTL_FILE.FCLOSE(L_FILE_HANDLE);</code>

<code>        </code><code>END_BOUNDARY(CONN);</code>

<code>      </code><code>EXCEPTION</code>

<code>        </code><code>WHEN</code> <code>OTHERS</code><code>THEN</code>

<code>          </code><code>UTL_FILE.FCLOSE(L_FILE_HANDLE);</code>

<code>          </code><code>END_BOUNDARY(CONN);</code>

<code>          </code><code>NULL</code><code>;</code>

<code>      </code><code>END</code><code>;</code><code>--结束文本类型附件的处理</code>

<code>    </code><code>ELSIF TRANSFER_ENC =</code><code>'base64'</code> <code>THEN</code>

<code>      </code><code>--如果是二进制类型的附件</code>

<code>        </code><code>L_FILEPOS  := 1;</code><code>--重置offset,在发送多个附件时,必须重置</code>

<code>        </code><code>L_FIL      := BFILENAME(DT_NAME, L_FILENAME);</code>

<code>        </code><code>L_FILE_LEN := DBMS_LOB.GETLENGTH(L_FIL);</code>

<code>        </code><code>L_MODULO   := MOD(L_FILE_LEN, L_AMT);</code>

<code>        </code><code>L_PIECES   := TRUNC(L_FILE_LEN / L_AMT);</code>

<code>        </code><code>IF (L_MODULO &lt;&gt; 0)</code><code>THEN</code>

<code>          </code><code>L_PIECES := L_PIECES + 1;</code>

<code>        </code><code>DBMS_LOB.FILEOPEN(L_FIL, DBMS_LOB.FILE_READONLY);</code>

<code>        </code><code>DBMS_LOB.</code><code>READ</code><code>(L_FIL, L_AMT, L_FILEPOS, L_BUF);</code>

<code>        </code><code>L_DATA :=</code><code>NULL</code><code>;</code>

<code>        </code><code>FOR</code> <code>I</code><code>IN</code> <code>1 .. L_PIECES LOOP</code>

<code>          </code><code>L_FILEPOS  := I * L_AMT + 1;</code>

<code>          </code><code>L_FILE_LEN := L_FILE_LEN - L_AMT;</code>

<code>          </code><code>L_DATA     := UTL_RAW.CONCAT(L_DATA, L_BUF);</code>

<code>          </code><code>L_CHUNKS   := TRUNC(UTL_RAW.LENGTH(L_DATA) / L_MAX_LINE_WIDTH);</code>

<code>          </code><code>IF (I &lt;&gt; L_PIECES)</code><code>THEN</code>

<code>            </code><code>L_CHUNKS := L_CHUNKS - 1;</code>

<code>          </code><code>END</code> <code>IF;</code>

<code>          </code><code>UTL_SMTP.WRITE_RAW_DATA(CONN, UTL_ENCODE.BASE64_ENCODE(L_DATA));</code>

<code>          </code><code>L_DATA :=</code><code>NULL</code><code>;</code>

<code>          </code><code>IF (L_FILE_LEN &lt; L_AMT</code><code>AND</code> <code>L_FILE_LEN &gt; 0)</code><code>THEN</code>

<code>            </code><code>L_AMT := L_FILE_LEN;</code>

<code>          </code><code>DBMS_LOB.</code><code>READ</code><code>(L_FIL, L_AMT, L_FILEPOS, L_BUF);</code>

<code>        </code><code>DBMS_LOB.FILECLOSE(L_FIL);</code>

<code>          </code><code>DBMS_LOB.FILECLOSE(L_FIL);</code>

<code>          </code><code>RAISE;</code>

<code>      </code><code>END</code><code>;</code><code>--结束处理二进制附件</code>

<code>    </code><code>END</code> <code>IF;</code><code>--结束处理附件内容</code>

<code>  </code><code>END</code><code>;</code><code>--结束过程ATTACHMENT</code>

<code>  </code><code>---------------------------------------------真正发送邮件的过程--------------------------------------------</code>

<code>  </code><code>PROCEDURE</code> <code>P_EMAIL(P_SENDORADDRESS2   VARCHAR2,</code><code>--发送地址</code>

<code>                    </code><code>P_RECEIVERADDRESS2 VARCHAR2)</code><code>--接受地址</code>

<code>   </code><code>IS</code>

<code>    </code><code>L_CONN UTL_SMTP.</code><code>CONNECTION</code><code>;</code><code>--定义连接</code>

<code>    </code><code>/*初始化邮件服务器信息,连接邮件服务器*/</code>

<code>    </code><code>L_CONN := UTL_SMTP.OPEN_CONNECTION(P_SERVER, P_PORT);</code>

<code>    </code><code>UTL_SMTP.HELO(L_CONN, P_SERVER);</code>

<code>    </code><code>/* smtp服务器登录校验 */</code>

<code>    </code><code>IF P_NEED_SMTP = 1</code><code>THEN</code>

<code>      </code><code>UTL_SMTP.COMMAND(L_CONN,</code><code>'AUTH LOGIN'</code><code>,</code><code>''</code><code>);</code>

<code>      </code><code>UTL_SMTP.COMMAND(L_CONN,</code>

<code>                       </code><code>UTL_RAW.CAST_TO_VARCHAR2(UTL_ENCODE.BASE64_ENCODE(UTL_RAW.CAST_TO_RAW(P_USER))));</code>

<code>                       </code><code>UTL_RAW.CAST_TO_VARCHAR2(UTL_ENCODE.BASE64_ENCODE(UTL_RAW.CAST_TO_RAW(P_PASS))));</code>

<code>    </code><code>/*设置发送地址和接收地址*/</code>

<code>    </code><code>UTL_SMTP.MAIL(L_CONN, P_SENDORADDRESS2);</code>

<code>    </code><code>UTL_SMTP.RCPT(L_CONN, P_RECEIVERADDRESS2);</code>

<code>    </code><code>/*设置邮件头*/</code>

<code>    </code><code>UTL_SMTP.OPEN_DATA(L_CONN);</code>

<code>    </code><code>WRITE_DATA(L_CONN,</code><code>'Date'</code><code>, TO_CHAR(SYSDATE,</code><code>'yyyy-mm-dd hh24:mi:ss'</code><code>));</code>

<code>    </code><code>/*设置发送人*/</code>

<code>    </code><code>WRITE_DATA(L_CONN,</code><code>'From'</code><code>, P_SENDOR);</code>

<code>    </code><code>/*设置接收人*/</code>

<code>    </code><code>WRITE_DATA(L_CONN,</code><code>'To'</code><code>, P_RECEIVER);</code>

<code>    </code><code>/*设置邮件主题*/</code>

<code>    </code><code>WRITE_DATA(L_CONN,</code><code>'Subject'</code><code>, P_SUB);</code>

<code>    </code><code>WRITE_DATA(L_CONN,</code><code>'Content-Type'</code><code>, MULTIPART_MIME_TYPE);</code>

<code>    </code><code>UTL_SMTP.WRITE_DATA(L_CONN, UTL_TCP.CRLF);</code>

<code>    </code><code>UTL_SMTP.WRITE_DATA(L_CONN, FIRST_BOUNDARY);</code>

<code>    </code><code>WRITE_DATA(L_CONN,</code><code>'Content-Type'</code><code>,</code><code>'text/plain;charset=gb2312'</code><code>);</code>

<code>    </code><code>--单独空一行,否则,正文内容不显示</code>

<code>    </code><code>/* 设置邮件正文</code>

<code>      </code><code>把分隔符还原成chr(10)。这主要是为了shell中调用该过程,如果有多行,则先把多行的内容合并成一行,并用 l_splite分隔</code>

<code>      </code><code>然后用 l_crlf替换chr(10)。这一步是必须的,否则将不能发送邮件正文有多行的邮件</code>

<code>    </code><code>*/</code>

<code>    </code><code>WRITE_DATA(L_CONN,</code>

<code>               </code><code>''</code><code>,</code>

<code>               </code><code>REPLACE</code><code>(</code><code>REPLACE</code><code>(P_TXT, L_SPLITE, CHR(10)), CHR(10), L_CRLF),</code>

<code>               </code><code>''</code><code>);</code>

<code>    </code><code>END_BOUNDARY(L_CONN);</code>

<code>    </code><code>--如果文件名称不为空,则发送附件</code>

<code>    </code><code>IF (P_FILENAME</code><code>IS</code> <code>NOT</code> <code>NULL</code><code>)</code><code>THEN</code>

<code>      </code><code>--根据逗号或者分号拆分附件地址</code>

<code>      </code><code>P_SPLITE_STR(P_FILENAME, 2);</code>

<code>      </code><code>--循环发送附件(在同一个邮件中)</code>

<code>      </code><code>FOR</code> <code>K</code><code>IN</code> <code>1 .. MY_ACCT_LIST.</code><code>COUNT</code> <code>LOOP</code>

<code>        </code><code>ATTACHMENT(CONN         =&gt; L_CONN,</code>

<code>                   </code><code>FILENAME     =&gt; MY_ACCT_LIST(K),</code>

<code>                   </code><code>TRANSFER_ENC =&gt; P_ENCODE,</code>

<code>                   </code><code>DT_NAME      =&gt; L_DIRECTORY_BASE_NAME || TO_CHAR(K));</code>

<code>      </code><code>END</code> <code>LOOP;</code>

<code>    </code><code>/*关闭数据写入*/</code>

<code>    </code><code>UTL_SMTP.CLOSE_DATA(L_CONN);</code>

<code>    </code><code>/*关闭连接*/</code>

<code>    </code><code>UTL_SMTP.QUIT(L_CONN);</code>

<code>    </code><code>/*异常处理*/</code>

<code>  </code><code>---------------------------------------------------主过程-----------------------------------------------------</code>

<code>BEGIN</code>

<code>  </code><code>L_SENDORADDRESS :=</code><code>'&lt;'</code> <code>|| P_SENDOR ||</code><code>'&gt;'</code><code>;</code>

<code>  </code><code>P_SPLITE_STR(P_RECEIVER);</code><code>--处理邮件地址</code>

<code>  </code><code>FOR</code> <code>K</code><code>IN</code> <code>1 .. MY_ADDRESS_LIST.</code><code>COUNT</code> <code>LOOP</code>

<code>    </code><code>P_EMAIL(L_SENDORADDRESS, MY_ADDRESS_LIST(K));</code>

<code>  </code><code>END</code> <code>LOOP;</code>

<code>  </code><code>/*处理邮件地址,根据逗号分割邮件*/</code>

<code>EXCEPTION</code>

<code>  </code><code>WHEN</code> <code>OTHERS</code><code>THEN</code>

<code>    </code><code>RAISE;</code>

<code>END</code><code>;</code>

转:http://www.cnblogs.com/IcefishBingqing/archive/2013/03/05/2944455.html

  

<code>PROCSENDEMAIL(</code><code>'邮件内容'</code><code>,</code><code>'邮件主题'</code><code>,</code><code>'发件人'</code><code>,</code><code>'收件人'</code><code>,</code><code>'邮件服务器ip地址'</code><code>,25,1,</code><code>'用户名'</code><code>,</code><code>'密码'</code><code>,</code><code>''</code><code>,</code><code>'base64'</code><code>);</code>

 注意邮件服务器一定要用ip,用域名不行。

文章可以转载,必须以链接形式标明出处。

本文转自 张冲andy 博客园博客,原文链接: http://www.cnblogs.com/andy6/p/5757606.html  ,如需转载请自行联系原作者