<?xml version="1.0" encoding="GB2312"?>
<rss version="2.0">
<channel>
<title>Friends Life and Oracle</title>
<link>http://www.eygle.com/blog/</link>
<description>eygle的Oracle Blog，提供Oracle技术研究及深入探讨，同时记录个人爱好及生活历程。</description>
<copyright>Copyright 2006</copyright>
<lastBuildDate>Sat, 15 Jul 2006 13:09:30 +0800</lastBuildDate>
<generator>http://www.movabletype.org/?v=3.33</generator>
<docs>http://blogs.law.harvard.edu/tech/rss</docs> 

<item>
<title>DBA Scripts:获取用户创建语句</title>
<description><![CDATA[<p>今天新开一个分类<strong style="COLOR: black; BACKGROUND-COLOR: #ff66ff">:</strong><a href="http://www.eygle.com/archives/database/scripts/">Scripts</a>,用来收集和记录一些DBA经常使用的脚本。<br />这些脚本有的来自网络，有的来自自己编写，记录在这里供大家参考，同时也给自己一个重新熟悉的过程。</p>
<p>很多时候我们在作数据库迁移时需要进行重建用户等工作,这时就需要获得用户信息,本脚本就用于获取用户的创建语句,具体脚本如下,来源Metalink<strong style="COLOR: black; BACKGROUND-COLOR: #ff66ff">:</strong></p>
<span class="Code"><blockquote dir="ltr" style="MARGIN-RIGHT: 0px">
<p dir="ltr" style="MARGIN-RIGHT: 0px">SET verify off;<br />SET termout off;<br />SET feedback off;<br />SET echo off;<br />SET pagesize 0;<br />SET timeing off;</p>
<p dir="ltr" style="MARGIN-RIGHT: 0px">SET termout on<br />SELECT 'Creating user build script...' FROM DUAL;<br />SET termout off;</p>
<p dir="ltr" style="MARGIN-RIGHT: 0px">CREATE TABLE usr_temp( lineno NUMBER,usr_name VARCHAR2(30),text VARCHAR2(80))<br />/</p>
<p dir="ltr" style="MARGIN-RIGHT: 0px">DECLARE<br />CURSOR usr_cursor<br />IS<br />SELECT username, PASSWORD, default_tablespace, temporary_tablespace,<br />PROFILE<br />FROM SYS.dba_users<br />WHERE username != 'SYS' <strong style="COLOR: black; BACKGROUND-COLOR: #99ff99">AND</strong> username != 'SYSTEM'<br />ORDER BY username;</p>
<p dir="ltr" style="MARGIN-RIGHT: 0px">CURSOR qta_cursor (c_usr VARCHAR2)<br />IS<br />SELECT tablespace_name, max_bytes<br />FROM SYS.dba_ts_quotas<br />WHERE username = c_usr;</p>
<p dir="ltr" style="MARGIN-RIGHT: 0px">lv_username SYS.dba_users.username%TYPE;<br />lv_password SYS.dba_users.PASSWORD%TYPE;<br />lv_default_tablespace SYS.dba_users.default_tablespace%TYPE;<br />lv_temporary_tablespace SYS.dba_users.default_tablespace%TYPE;<br />lv_profile SYS.dba_users.PROFILE%TYPE;<br />lv_tablespace_name SYS.dba_ts_quotas.tablespace_name%TYPE;<br />lv_max_bytes SYS.dba_ts_quotas.max_bytes%TYPE;<br />lv_string VARCHAR2 (80);<br />lv_lineno NUMBER <strong style="COLOR: black; BACKGROUND-COLOR: #ff66ff">:</strong>= 0;</p>
<p dir="ltr" style="MARGIN-RIGHT: 0px">PROCEDURE write_out (p_line INTEGER, p_name VARCHAR2, p_string VARCHAR2)<br />IS<br />BEGIN<br />INSERT INTO usr_temp<br />(lineno, usr_name, text<br />)<br />VALUES (p_line, p_name, p_string<br />);<br />END;<br />BEGIN<br />OPEN usr_cursor;</p>
<p dir="ltr" style="MARGIN-RIGHT: 0px">LOOP<br />FETCH usr_cursor<br />INTO lv_username, lv_password, lv_default_tablespace,<br />lv_temporary_tablespace, lv_profile;</p>
<p dir="ltr" style="MARGIN-RIGHT: 0px">EXIT WHEN usr_cursor%NOTFOUND;<br />lv_lineno <strong style="COLOR: black; BACKGROUND-COLOR: #ff66ff">:</strong>= 1;<br />lv_string <strong style="COLOR: black; BACKGROUND-COLOR: #ff66ff">:</strong>= ('CREATE USER ' || LOWER (lv_username));<br />write_out (lv_lineno, lv_username, lv_string);<br />lv_lineno <strong style="COLOR: black; BACKGROUND-COLOR: #ff66ff">:</strong>= lv_lineno + 1;</p>
<p dir="ltr" style="MARGIN-RIGHT: 0px">IF lv_password IS NULL<br />THEN<br />lv_string <strong style="COLOR: black; BACKGROUND-COLOR: #ff66ff">:</strong>= 'IDENTIFIED EXTERNALLY';<br />ELSE<br />lv_string <strong style="COLOR: black; BACKGROUND-COLOR: #ff66ff">:</strong>= ('IDENTIFIED BY VALUES ''' || lv_password || '''');<br />END IF;</p>
<p dir="ltr" style="MARGIN-RIGHT: 0px">write_out (lv_lineno, lv_username, lv_string);<br />lv_lineno <strong style="COLOR: black; BACKGROUND-COLOR: #ff66ff">:</strong>= lv_lineno + 1;<br />lv_string <strong style="COLOR: black; BACKGROUND-COLOR: #ff66ff">:</strong>= 'DEFAULT TABLESPACE ' || lv_default_tablespace;<br />write_out (lv_lineno, lv_username, lv_string);<br />lv_lineno <strong style="COLOR: black; BACKGROUND-COLOR: #ff66ff">:</strong>= lv_lineno + 1;<br />lv_string <strong style="COLOR: black; BACKGROUND-COLOR: #ff66ff">:</strong>= 'TEMPORARY TABLESPACE ' || lv_temporary_tablespace;<br />write_out (lv_lineno, lv_username, lv_string);<br />lv_lineno <strong style="COLOR: black; BACKGROUND-COLOR: #ff66ff">:</strong>= lv_lineno + 1;</p>
<p dir="ltr" style="MARGIN-RIGHT: 0px">OPEN qta_cursor (lv_username);</p>
<p dir="ltr" style="MARGIN-RIGHT: 0px">LOOP<br />FETCH qta_cursor<br />INTO lv_tablespace_name, lv_max_bytes;</p>
<p dir="ltr" style="MARGIN-RIGHT: 0px">EXIT WHEN qta_cursor%NOTFOUND;<br />lv_lineno <strong style="COLOR: black; BACKGROUND-COLOR: #ff66ff">:</strong>= lv_lineno + 1;</p>
<p dir="ltr" style="MARGIN-RIGHT: 0px">IF lv_max_bytes IS NULL<br />THEN<br />lv_string <strong style="COLOR: black; BACKGROUND-COLOR: #ff66ff">:</strong>= 'QUOTA UNLIMITED ON ' || lv_tablespace_name;<br />ELSE<br />lv_string <strong style="COLOR: black; BACKGROUND-COLOR: #ff66ff">:</strong>=<br />'QUOTA ' || lv_max_bytes || ' ON ' || lv_tablespace_name;<br />END IF;</p>
<p dir="ltr" style="MARGIN-RIGHT: 0px">write_out (lv_lineno, lv_username, lv_string);<br />END LOOP;</p>
<p dir="ltr" style="MARGIN-RIGHT: 0px">CLOSE qta_cursor;</p>
<p dir="ltr" style="MARGIN-RIGHT: 0px">lv_string <strong style="COLOR: black; BACKGROUND-COLOR: #ff66ff">:</strong>= ('PROFILE ' || lv_profile || ';');<br />write_out (lv_lineno, lv_username, lv_string);<br />lv_lineno <strong style="COLOR: black; BACKGROUND-COLOR: #ff66ff">:</strong>= lv_lineno + 1;<br />lv_string <strong style="COLOR: black; BACKGROUND-COLOR: #ff66ff">:</strong>= ' ';<br />write_out (lv_lineno, lv_username, lv_string);<br />END LOOP;</p>
<p dir="ltr" style="MARGIN-RIGHT: 0px">CLOSE usr_cursor;<br />END;<br />/</p>
<p dir="ltr" style="MARGIN-RIGHT: 0px">SPOOL create_users.sql<br />SET heading off<br />SET recsep off<br />COL test format a80 word_wrap</p>
<p dir="ltr" style="MARGIN-RIGHT: 0px"><br />SELECT text<br />FROM usr_temp<br />ORDER BY usr_name, lineno;</p>
<p dir="ltr" style="MARGIN-RIGHT: 0px">SPOOL off;</p>
<p dir="ltr" style="MARGIN-RIGHT: 0px">DROP TABLE usr_temp;<br />EXIT</p>
</blockquote>
<p dir="ltr" style="MARGIN-RIGHT: 0px">运行该脚本后会产生一个create_users.sql的输出文件,输出内容参考范例如下<strong style="COLOR: black; BACKGROUND-COLOR: #ff66ff">:</strong></p>
</span>
<table>
    <tbody>
        <tr>
            <td width="500" bgcolor="#999999">
            <p>CREATE USER dbsnmp<br />IDENTIFIED BY VALUES 'E066D214D5421CCC'<br />DEFAULT TABLESPACE SYSTEM<br />TEMPORARY TABLESPACE TEMP<br />PROFILE DEFAULT;</p>
            <p>CREATE USER eygle<br />IDENTIFIED BY VALUES 'B726E09FE21F8E83'<br />DEFAULT TABLESPACE EYGLE<br />TEMPORARY TABLESPACE TEMP<br />PROFILE DEFAULT;</p>
            <p>CREATE USER outln<br />IDENTIFIED BY VALUES '4A3BA55E08595C81'<br />DEFAULT TABLESPACE SYSTEM<br />TEMPORARY TABLESPACE TEMP<br />PROFILE DEFAULT;</p>
            <p>CREATE USER perfstat<br />IDENTIFIED BY VALUES 'AC98877DE1297365'<br />DEFAULT TABLESPACE PERFSTAT<br />TEMPORARY TABLESPACE TEMP<br />QUOTA -1 ON PERFSTAT<br />PROFILE DEFAULT;</p>
            <p>CREATE USER test<br />IDENTIFIED BY VALUES '7A0F2B316C212D67'<br />DEFAULT TABLESPACE TEST<br />TEMPORARY TABLESPACE TEMP<br />PROFILE DEFAULT;</p>
            <p>CREATE USER wmsys<br />IDENTIFIED BY VALUES '7C9BA362F8314299'<br />DEFAULT TABLESPACE SYSTEM<br />TEMPORARY TABLESPACE TEMP<br />PROFILE DEFAULT;</p>
            </td>
        </tr>
    </tbody>
</table>
<p>&nbsp;</p>
<p class="posted">&nbsp;</p>]]></description>
<link>http://www.eygle.com/archives/2006/07/dba_scripts_create_user.html</link>
<guid>http://www.eygle.com/archives/2006/07/dba_scripts_create_user.html</guid>
<category>Scripts</category>
<pubDate>Sat, 15 Jul 2006 13:09:30 +0800</pubDate>
</item>
<item>
<title>如何获得跟踪文件名称</title>
<description><![CDATA[<P class=style25 align=left>当我们使用sql_trace/10046等事件进行进程跟踪时，会生成跟踪文件.跟踪文件名称由以下几部分组成:</P>
<P class=style25 align=left>&lt;sid&gt;_ora_&lt;pid&gt;.trc</P>
<P class=style25 align=left>以下脚本用户获得跟踪文件名称:</P>
<P class=style25 align=left>For Unix:</P>
<DIV class="left style25" align=left>
<TABLE border=0>
<TBODY>
<TR>
<TD width=729 bgColor=#999999><SPAN class=style6>
<PRE>$ sqlplus "/ as sysdba"

SQL*Plus: Release 9.2.0.4.0 - Production on Fri Oct 8 12:08:09 2004

Copyright (c) 1982, 2002, Oracle Corporation.  All rights reserved.


Connected to:
Oracle9i Enterprise Edition Release 9.2.0.4.0 - 64bit Production
With the Partitioning, OLAP and Oracle Data Mining options
JServer Release 9.2.0.4.0 - Production

SQL&gt; set echo on
SQL&gt; @gettrcnameunix
SQL&gt; SELECT       d.VALUE
  2         || '/'
  3         || LOWER (RTRIM (i.INSTANCE, CHR (0)))
  4         || '_ora_'
  5         || p.spid
  6         || '.trc' trace_file_name
  7    FROM (SELECT p.spid
  8            FROM v$mystat m, v$session s, v$process p
  9           WHERE m.statistic# = 1 AND s.SID = m.SID AND p.addr = s.paddr) p,
 10         (SELECT t.INSTANCE
 11            FROM v$thread t, v$parameter v
 12           WHERE v.NAME = 'thread'
 13             AND (v.VALUE = 0 OR t.thread# = TO_NUMBER (v.VALUE))) i,
 14         (SELECT VALUE
 15            FROM v$parameter
 16           WHERE NAME = 'user_dump_dest') d
 17  /

TRACE_FILE_NAME
--------------------------------------------------------------------------------
/opt/oracle/admin/hsbill/udump/hsbill_ora_29630.trc       
                      </PRE></SPAN></TD></TR></TBODY></TABLE>
<P>For Nt: </P>
<TABLE cellSpacing=0 cellPadding=0 bgColor=#999999>
<TBODY>
<TR>
<TD class=style6 vAlign=top width=736>

<P>&nbsp;</P><PRE>&nbsp;
SQL&gt; SELECT    d.VALUE
  2         || '\'
  3         || LOWER (RTRIM (i.INSTANCE, CHR (0)))
  4         || '_ora_'
  5         || p.spid
  6         || '.trc' trace_file_name
  7    FROM (SELECT p.spid
  8            FROM v$mystat m, v$session s, v$process p
  9           WHERE m.statistic# = 1 AND s.SID = m.SID AND p.addr = s.paddr) p,
 10         (SELECT t.INSTANCE
 11            FROM v$thread t, v$parameter v
 12           WHERE v.NAME = 'thread'
 13             AND (v.VALUE = 0 OR t.thread# = TO_NUMBER (v.VALUE))) i,
 14         (SELECT VALUE
 15            FROM v$parameter
 16           WHERE NAME = 'user_dump_dest') d
 17  /

TRACE_FILE_NAME
--------------------------------------------------------------------------------
e:\oracle\admin\eygle\udump\eygle_ora_3084.trc
       </PRE></TD></TR></TBODY></TABLE>
<P>&nbsp;</P>
<P>你可以在这里下载以上脚本:<A href="http://www.eygle.com/faq/script/gettrcnameunix.sql">ForUnix</A> <A href="http://www.eygle.com/faq/script/gettrcnament.sql">ForNt</A> </P>
<P>&nbsp;</P></DIV>]]></description>
<link>http://www.eygle.com/archives/2004/12/howto_get_trace_filename.html</link>
<guid>http://www.eygle.com/archives/2004/12/howto_get_trace_filename.html</guid>
<category>HowTo</category>
<pubDate>Thu, 16 Dec 2004 19:59:21 +0800</pubDate>
</item>
<item>
<title>Oracle HowTo:如何查看各个表空间的自由空间</title>
<description><![CDATA[DBA_FREE_SPACE视图记录了数据库中所有表空间的自由extents情况，所以可以从该视图获得各表空间自由空间情况。<br>
<br>
<table><td width="500" bgcolor="#999999"> <pre>
SQL> desc dba_free_space
 Name                         Null?    Type
 ----------------------- ------------- -----------------
 TABLESPACE_NAME                       VARCHAR2(30)
 FILE_ID                               NUMBER
 BLOCK_ID                              NUMBER
 BYTES                                 NUMBER
 BLOCKS                                NUMBER
 RELATIVE_FNO                          NUMBER
</pre></td></table><br>


可以使用如下SQL进行查询:<br>
<table><td width="500" bgcolor="#999999"> <pre>
select tablespace_name,sum(bytes)/1024/1024 free_Mbytes
from dba_free_space
group by tablespace_name
order by free_Mbytes
/
</pre></td></table><br>

<br>
示例输出:<br>
<table><td width="500" bgcolor="#999999"> <pre>
SQL> select tablespace_name,sum(bytes)/1024/1024 free_Mbytes
  2  from dba_free_space
  3  group by tablespace_name
  4  order by free_Mbytes
  5  /

TABLESPACE_NAME      FREE_MBYTES
-------------------- -----------
USERS                        .75
UNDOTBS1                 18.6875
SYSTEM                   42.6875
</pre></td></table><br>
]]></description>
<link>http://www.eygle.com/archives/2004/10/get_free_space.html</link>
<guid>http://www.eygle.com/archives/2004/10/get_free_space.html</guid>
<category>HowTo</category>
<pubDate>Thu, 14 Oct 2004 09:55:32 +0800</pubDate>
</item>
<item>
<title>如何在Oracle中发送Email</title>
<description><![CDATA[在Oracle中发送email，以下是Oracle提供的例子，供参考.<br>
itpub link:<br>
<A href="http://www.itpub.net/showthread.php?threadid=226086">http://www.itpub.net/showthread.php?threadid=226086</A> <br>
<P class=style6>1.<SPAN class=style15> CREATE PACKAGE</SPAN></P>
<TABLE width=626 border=0>
<TBODY>
<TR>
<TD class=style6 width=620 bgColor=#dddddd>
<P class=style5>&nbsp;</P>
<P class=style5>CREATE OR REPLACE PACKAGE demo_mail IS</P>
<P class=style5>----------------------- Customizable Section -----------------------</P>
<P class=style5>-- Customize the SMTP host, port and your domain name below.<BR>smtp_host VARCHAR2(256) := <SPAN class=style13><FONT color=#ff0000>'smtp.eygle.com'</FONT></SPAN>;<BR>smtp_port PLS_INTEGER := 25;<BR>smtp_domain VARCHAR2(256) :=<SPAN class=style13><FONT color=#ff0000> 'eygle.com'</FONT></SPAN>;</P>
<P class=style5>-- Customize the signature that will appear in the email's MIME header.<BR>-- Useful for versioning.<BR>MAILER_ID CONSTANT VARCHAR2(256) :=<SPAN class=style13><FONT color=#ff0000> 'Mailer by Eygle'</FONT></SPAN>;</P>
<P class=style5>--------------------- End Customizable Section ---------------------</P>
<P class=style5>-- A unique string that demarcates boundaries of parts in a multi-part email<BR>-- The string should not appear inside the body of any part of the email.<BR>-- Customize this if needed or generate this randomly dynamically.<BR>BOUNDARY CONSTANT VARCHAR2(256) := '-----7D81B75CCC90D2974F7A1CBD';</P>
<P class=style5>FIRST_BOUNDARY CONSTANT VARCHAR2(256) := '--' || BOUNDARY || utl_tcp.CRLF;<BR>LAST_BOUNDARY CONSTANT VARCHAR2(256) := '--' || BOUNDARY || '--' ||<BR>utl_tcp.CRLF;</P>
<P class=style5>-- A MIME type that denotes multi-part email (MIME) messages.<BR>MULTIPART_MIME_TYPE CONSTANT VARCHAR2(256) := 'multipart/mixed; boundary="'||<BR>BOUNDARY || '"';<BR>MAX_BASE64_LINE_WIDTH CONSTANT PLS_INTEGER := 76 / 4 * 3;</P>
<P class=style5>-- A simple email API for sending email in plain text in a single call.<BR>-- The format of an email address is one of these:<BR>-- someone@some-domain<BR>-- "Someone at some domain" &lt;someone@some-domain&gt;<BR>-- Someone at some domain &lt;someone@some-domain&gt;<BR>-- The recipients is a list of email addresses separated by<BR>-- either a "," or a ";"<BR>PROCEDURE mail(sender IN VARCHAR2,<BR>recipients IN VARCHAR2,<BR>subject IN VARCHAR2,<BR>message IN VARCHAR2);</P>
<P class=style5>-- Extended email API to send email in HTML or plain text with no size limit.<BR>-- First, begin the email by begin_mail(). Then, call write_text() repeatedly<BR>-- to send email in ASCII piece-by-piece. Or, call write_mb_text() to send<BR>-- email in non-ASCII or multi-byte character set. End the email with<BR>-- end_mail().<BR>FUNCTION begin_mail(sender IN VARCHAR2,<BR>recipients IN VARCHAR2,<BR>subject IN VARCHAR2,<BR>mime_type IN VARCHAR2 DEFAULT 'text/plain',<BR>priority IN PLS_INTEGER DEFAULT NULL)<BR>RETURN utl_smtp.connection;</P>
<P class=style5>-- Write email body in ASCII<BR>PROCEDURE write_text(conn IN OUT NOCOPY utl_smtp.connection,<BR>message IN VARCHAR2);</P>
<P class=style5>-- Write email body in non-ASCII (including multi-byte). The email body<BR>-- will be sent in the database character set.<BR>PROCEDURE write_mb_text(conn IN OUT NOCOPY utl_smtp.connection,<BR>message IN VARCHAR2);</P>
<P class=style5>-- Write email body in binary<BR>PROCEDURE write_raw(conn IN OUT NOCOPY utl_smtp.connection,<BR>message IN RAW);</P>
<P class=style5>-- APIs to send email with attachments. Attachments are sent by sending<BR>-- emails in "multipart/mixed" MIME format. Specify that MIME format when<BR>-- beginning an email with begin_mail().</P>
<P class=style5>-- Send a single text attachment.<BR>PROCEDURE attach_text(conn IN OUT NOCOPY utl_smtp.connection,<BR>data IN VARCHAR2,<BR>mime_type IN VARCHAR2 DEFAULT 'text/plain',<BR>inline IN BOOLEAN DEFAULT TRUE,<BR>filename IN VARCHAR2 DEFAULT NULL,<BR>last IN BOOLEAN DEFAULT FALSE);</P>
<P class=style5>-- Send a binary attachment. The attachment will be encoded in Base-64<BR>-- encoding format.<BR>PROCEDURE attach_base64(conn IN OUT NOCOPY utl_smtp.connection,<BR>data IN RAW,<BR>mime_type IN VARCHAR2 DEFAULT 'application/octet',<BR>inline IN BOOLEAN DEFAULT TRUE,<BR>filename IN VARCHAR2 DEFAULT NULL,<BR>last IN BOOLEAN DEFAULT FALSE);</P>
<P class=style5>-- Send an attachment with no size limit. First, begin the attachment<BR>-- with begin_attachment(). Then, call write_text repeatedly to send<BR>-- the attachment piece-by-piece. If the attachment is text-based but<BR>-- in non-ASCII or multi-byte character set, use write_mb_text() instead.<BR>-- To send binary attachment, the binary content should first be<BR>-- encoded in Base-64 encoding format using the demo package for 8i,<BR>-- or the native one in 9i. End the attachment with end_attachment.<BR>PROCEDURE begin_attachment(conn IN OUT NOCOPY utl_smtp.connection,<BR>mime_type IN VARCHAR2 DEFAULT 'text/plain',<BR>inline IN BOOLEAN DEFAULT TRUE,<BR>filename IN VARCHAR2 DEFAULT NULL,<BR>transfer_enc IN VARCHAR2 DEFAULT NULL);</P>
<P class=style5>-- End the attachment.<BR>PROCEDURE end_attachment(conn IN OUT NOCOPY utl_smtp.connection,<BR>last IN BOOLEAN DEFAULT FALSE);</P>
<P class=style5>-- End the email.<BR>PROCEDURE end_mail(conn IN OUT NOCOPY utl_smtp.connection);</P>
<P class=style5>-- Extended email API to send multiple emails in a session for better<BR>-- performance. First, begin an email session with begin_session.<BR>-- Then, begin each email with a session by calling begin_mail_in_session<BR>-- instead of begin_mail. End the email with end_mail_in_session instead<BR>-- of end_mail. End the email session by end_session.<BR>FUNCTION begin_session RETURN utl_smtp.connection;</P>
<P class=style5>-- Begin an email in a session.<BR>PROCEDURE begin_mail_in_session(conn IN OUT NOCOPY utl_smtp.connection,<BR>sender IN VARCHAR2,<BR>recipients IN VARCHAR2,<BR>subject IN VARCHAR2,<BR>mime_type IN VARCHAR2 DEFAULT 'text/plain',<BR>priority IN PLS_INTEGER DEFAULT NULL);</P>
<P class=style5>-- End an email in a session.<BR>PROCEDURE end_mail_in_session(conn IN OUT NOCOPY utl_smtp.connection);</P>
<P class=style5>-- End an email session.<BR>PROCEDURE end_session(conn IN OUT NOCOPY utl_smtp.connection);</P>
<P class=style5>END;<BR>/<BR>CREATE OR REPLACE PACKAGE BODY demo_mail IS</P>
<P class=style5>-- Return the next email address in the list of email addresses, separated<BR>-- by either a "," or a ";". The format of mailbox may be in one of these:<BR>-- someone@some-domain<BR>-- "Someone at some domain" &lt;someone@some-domain&gt;<BR>-- Someone at some domain &lt;someone@some-domain&gt;<BR>FUNCTION get_address(addr_list IN OUT VARCHAR2) RETURN VARCHAR2 IS</P>
<P class=style5>addr VARCHAR2(256);<BR>i pls_integer;</P>
<P class=style5>FUNCTION lookup_unquoted_char(str IN VARCHAR2,<BR>chrs IN VARCHAR2) RETURN pls_integer AS<BR>c VARCHAR2(5);<BR>i pls_integer;<BR>len pls_integer;<BR>inside_quote BOOLEAN;<BR>BEGIN<BR>inside_quote := false;<BR>i := 1;<BR>len := length(str);<BR>WHILE (i &lt;= len) LOOP</P>
<P class=style5>c := substr(str, i, 1);</P>
<P class=style5>IF (inside_quote) THEN<BR>IF (c = '"') THEN<BR>inside_quote := false;<BR>ELSIF (c = '\') THEN<BR>i := i + 1; -- Skip the quote character<BR>END IF;<BR>GOTO next_char;<BR>END IF;</P>
<P class=style5>IF (c = '"') THEN<BR>inside_quote := true;<BR>GOTO next_char;<BR>END IF;</P>
<P class=style5>IF (instr(chrs, c) &gt;= 1) THEN<BR>RETURN i;<BR>END IF;</P>
<P class=style5>&lt;&lt;next_char&gt;&gt;<BR>i := i + 1;</P>
<P class=style5>END LOOP;</P>
<P class=style5>RETURN 0;</P>
<P class=style5>END;</P>
<P class=style5>BEGIN</P>
<P class=style5>addr_list := ltrim(addr_list);<BR>i := lookup_unquoted_char(addr_list, ',;');<BR>IF (i &gt;= 1) THEN<BR>addr := substr(addr_list, 1, i - 1);<BR>addr_list := substr(addr_list, i + 1);<BR>ELSE<BR>addr := addr_list;<BR>addr_list := '';<BR>END IF;</P>
<P class=style5>i := lookup_unquoted_char(addr, '&lt;');<BR>IF (i &gt;= 1) THEN<BR>addr := substr(addr, i + 1);<BR>i := instr(addr, '&gt;');<BR>IF (i &gt;= 1) THEN<BR>addr := substr(addr, 1, i - 1);<BR>END IF;<BR>END IF;</P>
<P class=style5>RETURN addr;<BR>END;</P>
<P class=style5>-- Write a MIME header<BR>PROCEDURE write_mime_header(conn IN OUT NOCOPY utl_smtp.connection,<BR>name IN VARCHAR2,<BR>value IN VARCHAR2) IS<BR>BEGIN<BR>utl_smtp.write_data(conn, name || ': ' || value || utl_tcp.CRLF);<BR>END;</P>
<P class=style5>-- Mark a message-part boundary. Set &lt;last&gt; to TRUE for the last boundary.<BR>PROCEDURE write_boundary(conn IN OUT NOCOPY utl_smtp.connection,<BR>last IN BOOLEAN DEFAULT FALSE) AS<BR>BEGIN<BR>IF (last) THEN<BR>utl_smtp.write_data(conn, LAST_BOUNDARY);<BR>ELSE<BR>utl_smtp.write_data(conn, FIRST_BOUNDARY);<BR>END IF;<BR>END;</P>
<P class=style5>------------------------------------------------------------------------<BR>PROCEDURE mail(sender IN VARCHAR2,<BR>recipients IN VARCHAR2,<BR>subject IN VARCHAR2,<BR>message IN VARCHAR2) IS<BR>conn utl_smtp.connection;<BR>BEGIN<BR>conn := begin_mail(sender, recipients, subject);<BR>write_text(conn, message);<BR>end_mail(conn);<BR>END;</P>
<P class=style5>------------------------------------------------------------------------<BR>FUNCTION begin_mail(sender IN VARCHAR2,<BR>recipients IN VARCHAR2,<BR>subject IN VARCHAR2,<BR>mime_type IN VARCHAR2 DEFAULT 'text/plain',<BR>priority IN PLS_INTEGER DEFAULT NULL)<BR>RETURN utl_smtp.connection IS<BR>conn utl_smtp.connection;<BR>BEGIN<BR>conn := begin_session;<BR>begin_mail_in_session(conn, sender, recipients, subject, mime_type,<BR>priority);<BR>RETURN conn;<BR>END;</P>
<P class=style5>------------------------------------------------------------------------<BR>PROCEDURE write_text(conn IN OUT NOCOPY utl_smtp.connection,<BR>message IN VARCHAR2) IS<BR>BEGIN<BR>utl_smtp.write_data(conn, message);<BR>END;</P>
<P class=style5>------------------------------------------------------------------------<BR>PROCEDURE write_mb_text(conn IN OUT NOCOPY utl_smtp.connection,<BR>message IN VARCHAR2) IS<BR>BEGIN<BR>utl_smtp.write_raw_data(conn, utl_raw.cast_to_raw(message));<BR>END;</P>
<P class=style5>------------------------------------------------------------------------<BR>PROCEDURE write_raw(conn IN OUT NOCOPY utl_smtp.connection,<BR>message IN RAW) IS<BR>BEGIN<BR>utl_smtp.write_raw_data(conn, message);<BR>END;</P>
<P class=style5>------------------------------------------------------------------------<BR>PROCEDURE attach_text(conn IN OUT NOCOPY utl_smtp.connection,<BR>data IN VARCHAR2,<BR>mime_type IN VARCHAR2 DEFAULT 'text/plain',<BR>inline IN BOOLEAN DEFAULT TRUE,<BR>filename IN VARCHAR2 DEFAULT NULL,<BR>last IN BOOLEAN DEFAULT FALSE) IS<BR>BEGIN<BR>begin_attachment(conn, mime_type, inline, filename);<BR>write_text(conn, data);<BR>end_attachment(conn, last);<BR>END;</P>
<P class=style5>------------------------------------------------------------------------<BR>PROCEDURE attach_base64(conn IN OUT NOCOPY utl_smtp.connection,<BR>data IN RAW,<BR>mime_type IN VARCHAR2 DEFAULT 'application/octet',<BR>inline IN BOOLEAN DEFAULT TRUE,<BR>filename IN VARCHAR2 DEFAULT NULL,<BR>last IN BOOLEAN DEFAULT FALSE) IS<BR>i PLS_INTEGER;<BR>len PLS_INTEGER;<BR>BEGIN</P>
<P class=style5>begin_attachment(conn, mime_type, inline, filename, 'base64');</P>
<P class=style5>-- Split the Base64-encoded attachment into multiple lines<BR>i := 1;<BR>len := utl_raw.length(data);<BR>WHILE (i &lt; len) LOOP<BR>IF (i + MAX_BASE64_LINE_WIDTH &lt; len) THEN<BR>utl_smtp.write_raw_data(conn,<BR>utl_encode.base64_encode(utl_raw.substr(data, i,<BR>MAX_BASE64_LINE_WIDTH)));<BR>ELSE<BR>utl_smtp.write_raw_data(conn,<BR>utl_encode.base64_encode(utl_raw.substr(data, i)));<BR>END IF;<BR>utl_smtp.write_data(conn, utl_tcp.CRLF);<BR>i := i + MAX_BASE64_LINE_WIDTH;<BR>END LOOP;</P>
<P class=style5>end_attachment(conn, last);</P>
<P class=style5>END;</P>
<P class=style5>------------------------------------------------------------------------<BR>PROCEDURE begin_attachment(conn IN OUT NOCOPY utl_smtp.connection,<BR>mime_type IN VARCHAR2 DEFAULT 'text/plain',<BR>inline IN BOOLEAN DEFAULT TRUE,<BR>filename IN VARCHAR2 DEFAULT NULL,<BR>transfer_enc IN VARCHAR2 DEFAULT NULL) IS<BR>BEGIN<BR>write_boundary(conn);<BR>write_mime_header(conn, 'Content-Type', mime_type);</P>
<P class=style5>IF (filename IS NOT NULL) THEN<BR>IF (inline) THEN<BR>write_mime_header(conn, 'Content-Disposition',<BR>'inline; filename="'||filename||'"');<BR>ELSE<BR>write_mime_header(conn, 'Content-Disposition',<BR>'attachment; filename="'||filename||'"');<BR>END IF;<BR>END IF;</P>
<P class=style5>IF (transfer_enc IS NOT NULL) THEN<BR>write_mime_header(conn, 'Content-Transfer-Encoding', transfer_enc);<BR>END IF;</P>
<P class=style5>utl_smtp.write_data(conn, utl_tcp.CRLF);<BR>END;</P>
<P class=style5>------------------------------------------------------------------------<BR>PROCEDURE end_attachment(conn IN OUT NOCOPY utl_smtp.connection,<BR>last IN BOOLEAN DEFAULT FALSE) IS<BR>BEGIN<BR>utl_smtp.write_data(conn, utl_tcp.CRLF);<BR>IF (last) THEN<BR>write_boundary(conn, last);<BR>END IF;<BR>END;</P>
<P class=style5>------------------------------------------------------------------------<BR>PROCEDURE end_mail(conn IN OUT NOCOPY utl_smtp.connection) IS<BR>BEGIN<BR>end_mail_in_session(conn);<BR>end_session(conn);<BR>END;</P>
<P class=style5>------------------------------------------------------------------------<BR>FUNCTION begin_session RETURN utl_smtp.connection IS<BR>conn utl_smtp.connection;<BR>BEGIN<BR>-- open SMTP connection<BR>conn := utl_smtp.open_connection(smtp_host, smtp_port);<BR>utl_smtp.helo(conn, smtp_domain);<BR>RETURN conn;<BR>END;</P>
<P class=style5>------------------------------------------------------------------------<BR>PROCEDURE begin_mail_in_session(conn IN OUT NOCOPY utl_smtp.connection,<BR>sender IN VARCHAR2,<BR>recipients IN VARCHAR2,<BR>subject IN VARCHAR2,<BR>mime_type IN VARCHAR2 DEFAULT 'text/plain',<BR>priority IN PLS_INTEGER DEFAULT NULL) IS<BR>my_recipients VARCHAR2(32767) := recipients;<BR>my_sender VARCHAR2(32767) := sender;<BR>BEGIN</P>
<P class=style5>-- Specify sender's address (our server allows bogus address<BR>-- as long as it is a full email address (xxx@yyy.com).<BR>utl_smtp.mail(conn, get_address(my_sender));</P>
<P class=style5>-- Specify recipient(s) of the email.<BR>WHILE (my_recipients IS NOT NULL) LOOP<BR>utl_smtp.rcpt(conn, get_address(my_recipients));<BR>END LOOP;</P>
<P class=style5>-- Start body of email<BR>utl_smtp.open_data(conn);</P>
<P class=style5>-- Set "From" MIME header<BR>write_mime_header(conn, 'From', sender);</P>
<P class=style5>-- Set "To" MIME header<BR>write_mime_header(conn, 'To', recipients);</P>
<P class=style5>-- Set "Subject" MIME header<BR>write_mime_header(conn, 'Subject', subject);</P>
<P class=style5>-- Set "Content-Type" MIME header<BR>write_mime_header(conn, 'Content-Type', mime_type);</P>
<P class=style5>-- Set "X-Mailer" MIME header<BR>write_mime_header(conn, 'X-Mailer', MAILER_ID);</P>
<P class=style5>-- Set priority:<BR>-- High Normal Low<BR>-- 1 2 3 4 5<BR>IF (priority IS NOT NULL) THEN<BR>write_mime_header(conn, 'X-Priority', priority);<BR>END IF;</P>
<P class=style5>-- Send an empty line to denotes end of MIME headers and<BR>-- beginning of message body.<BR>utl_smtp.write_data(conn, utl_tcp.CRLF);</P>
<P class=style5>IF (mime_type LIKE 'multipart/mixed%') THEN<BR>write_text(conn, 'This is a multi-part message in MIME format.' ||<BR>utl_tcp.crlf);<BR>END IF;</P>
<P class=style5>END;</P>
<P class=style5>------------------------------------------------------------------------<BR>PROCEDURE end_mail_in_session(conn IN OUT NOCOPY utl_smtp.connection) IS<BR>BEGIN<BR>utl_smtp.close_data(conn);<BR>END;</P>
<P class=style5>------------------------------------------------------------------------<BR>PROCEDURE end_session(conn IN OUT NOCOPY utl_smtp.connection) IS<BR>BEGIN<BR>utl_smtp.quit(conn);<BR>END;</P>
<P class=style5>END;<BR>/</P>
<P></P></TD></TR></TBODY></TABLE>
<P class=style6>2.发送 MAIL：</P>
<TABLE width=625 border=0>
<TBODY>
<TR>
<TD class=style6 bgColor=#dddddd>


<P class=style5>&nbsp;</P>
<P class=style5>CREATE OR REPLACE procedure MailTest IS<BR>Begin<BR>DEMO_MAIL.mail('eygle@itpub.net',<BR>'gqgai@hurray.com.cn',<BR>'Just a test',<BR>'It is ok.');<BR>end;<BR>/ </P>
<P class=style5>begin<BR>MailTest;<BR>end;</P>
&nbsp;</TD></TR></TBODY></TABLE>
<P class=style1>&nbsp;</P>]]></description>
<link>http://www.eygle.com/archives/2004/06/oracle_mail.html</link>
<guid>http://www.eygle.com/archives/2004/06/oracle_mail.html</guid>
<category>Scripts</category>
<pubDate>Thu, 24 Jun 2004 21:07:07 +0800</pubDate>
</item>


</channel>
</rss>