<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-空间站-文章分类-数据库</title><link>http://www.blogjava.net/i369/category/17107.html</link><description>北极心空</description><language>zh-cn</language><lastBuildDate>Thu, 03 Apr 2008 05:14:21 GMT</lastBuildDate><pubDate>Thu, 03 Apr 2008 05:14:21 GMT</pubDate><ttl>60</ttl><item><title>[收藏] Java数据类型，Hibernate数据类型，标准sql数据类型之间的对应表 </title><link>http://www.blogjava.net/i369/articles/190588.html</link><dc:creator>芦苇</dc:creator><author>芦苇</author><pubDate>Thu, 03 Apr 2008 04:39:00 GMT</pubDate><guid>http://www.blogjava.net/i369/articles/190588.html</guid><wfw:comment>http://www.blogjava.net/i369/comments/190588.html</wfw:comment><comments>http://www.blogjava.net/i369/articles/190588.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/i369/comments/commentRss/190588.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/i369/services/trackbacks/190588.html</trackback:ping><description><![CDATA[<table style="border-right: #f3f3f3 5px solid; border-top: #f3f3f3 5px solid; border-left: #f3f3f3 5px solid; border-bottom: #f3f3f3 5px solid" cellspacing="0" cellpadding="0" width="100%" border="0">
    <tbody>
        <tr>
            <td style="padding-left: 10px; padding-top: 5px" width="560" colspan="2"><span style="font-size: 13px; line-height: 22px">
            <div class="postTitle"><a class="postTitle2" id="viewpost1_TitleUrl" href="http://www.blogjava.net/haoqingshi/articles/10912.html">Java数据类型，Hibernate数据类型，标准sql数据类型之间的对应表</a></div>
            <table style="width: 100%; text-align: left" cellspacing="2" cellpadding="2" border="1">
                <tbody>
                    <tr>
                        <td style="background-color: rgb(204,204,204)"><small><font size="2">Java数据类型</font></small></td>
                        <td style="background-color: rgb(204,204,204)"><small><font size="2">Hibernate数据类型</font></small></td>
                        <td style="background-color: rgb(204,204,204)"><small><font size="2">标准SQL数据类型<br />
                        (PS:对于不同的DB可能有所差异)</font></small></td>
                    </tr>
                    <tr>
                        <td>byte、java.lang.Byte</td>
                        <td>byte</td>
                        <td>TINYINT</td>
                    </tr>
                    <tr>
                        <td>short、java.lang.Short</td>
                        <td>short</td>
                        <td>SMALLINT</td>
                    </tr>
                    <tr>
                        <td>int、java.lang.Integer</td>
                        <td>integer</td>
                        <td>INGEGER</td>
                    </tr>
                    <tr>
                        <td>long、java.lang.Long</td>
                        <td>long</td>
                        <td>BIGINT</td>
                    </tr>
                    <tr>
                        <td>float、java.lang.Float</td>
                        <td>float</td>
                        <td>FLOAT</td>
                    </tr>
                    <tr>
                        <td>double、java.lang.Double</td>
                        <td>double</td>
                        <td>DOUBLE</td>
                    </tr>
                    <tr>
                        <td>java.math.BigDecimal</td>
                        <td>big_decimal</td>
                        <td>NUMERIC</td>
                    </tr>
                    <tr>
                        <td>char、java.lang.Character</td>
                        <td>character</td>
                        <td>CHAR(1)</td>
                    </tr>
                    <tr>
                        <td>boolean、java.lang.Boolean</td>
                        <td>boolean</td>
                        <td>BIT</td>
                    </tr>
                    <tr>
                        <td>java.lang.String</td>
                        <td>string</td>
                        <td>VARCHAR</td>
                    </tr>
                    <tr>
                        <td>boolean、java.lang.Boolean</td>
                        <td>yes_no</td>
                        <td>CHAR(1)('Y'或'N')</td>
                    </tr>
                    <tr>
                        <td>boolean、java.lang.Boolean</td>
                        <td>true_false</td>
                        <td>CHAR(1)('Y'或'N')</td>
                    </tr>
                    <tr>
                        <td>java.util.Date、java.sql.Date</td>
                        <td>date</td>
                        <td>DATE</td>
                    </tr>
                    <tr>
                        <td>java.util.Date、java.sql.Time</td>
                        <td>time</td>
                        <td>TIME</td>
                    </tr>
                    <tr>
                        <td>java.util.Date、java.sql.Timestamp</td>
                        <td>timestamp</td>
                        <td>TIMESTAMP</td>
                    </tr>
                    <tr>
                        <td>java.util.Calendar</td>
                        <td>calendar</td>
                        <td>TIMESTAMP</td>
                    </tr>
                    <tr>
                        <td>java.util.Calendar</td>
                        <td>calendar_date</td>
                        <td>DATE</td>
                    </tr>
                    <tr>
                        <td>byte[]</td>
                        <td>binary</td>
                        <td>VARBINARY、BLOB</td>
                    </tr>
                    <tr>
                        <td>java.lang.String</td>
                        <td>text</td>
                        <td>CLOB</td>
                    </tr>
                    <tr>
                        <td>java.io.Serializable</td>
                        <td>serializable</td>
                        <td>VARBINARY、BLOB</td>
                    </tr>
                    <tr>
                        <td>java.sql.Clob</td>
                        <td>clob</td>
                        <td>CLOB</td>
                    </tr>
                    <tr>
                        <td>java.sql.Blob</td>
                        <td>blob</td>
                        <td>BLOB</td>
                    </tr>
                    <tr>
                        <td>java.lang.Class</td>
                        <td>class</td>
                        <td>VARCHAR</td>
                    </tr>
                    <tr>
                        <td>java.util.Locale</td>
                        <td>locale</td>
                        <td>VARCHAR</td>
                    </tr>
                    <tr>
                        <td>java.util.TimeZone</td>
                        <td>timezone</td>
                        <td>VARCHAR</td>
                    </tr>
                    <tr>
                        <td>java.util.Currency</td>
                        <td>currency</td>
                        <td>VARCHAR</td>
                    </tr>
                </tbody>
            </table>
            </span></td>
        </tr>
        <tr>
            <td valign="bottom" colspan="2" height="40">文章来源:<a href="http://www.blogjava.net/haoqingshi/articles/10912.html" target="_blank">http://www.blogjava.net/haoqingshi/articles/10912.html</a></td>
        </tr>
    </tbody>
</table>
<img src ="http://www.blogjava.net/i369/aggbug/190588.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/i369/" target="_blank">芦苇</a> 2008-04-03 12:39 <a href="http://www.blogjava.net/i369/articles/190588.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title> 几种流行的数据库SQL分页 </title><link>http://www.blogjava.net/i369/articles/183602.html</link><dc:creator>芦苇</dc:creator><author>芦苇</author><pubDate>Tue, 04 Mar 2008 01:14:00 GMT</pubDate><guid>http://www.blogjava.net/i369/articles/183602.html</guid><wfw:comment>http://www.blogjava.net/i369/comments/183602.html</wfw:comment><comments>http://www.blogjava.net/i369/articles/183602.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/i369/comments/commentRss/183602.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/i369/services/trackbacks/183602.html</trackback:ping><description><![CDATA[<div class="postTitle">1.<font color="#ff0000">Oracle</font>:</div>
<div class="postText">
<p>&nbsp; select * from ( select row_.*, rownum rownum_ from ( query_SQL ) row_ where rownum =&lt; max) where rownum_ &gt;= min</p>
<p>&nbsp;2.<font color="#ff0000">SQL Server</font>:</p>
<p>&nbsp; select top @pagesize * from tablename where id not in (select top @pagesize*(@page-1) id from tablename order by id) order by id</p>
<p>&nbsp;3.<font color="#ff0000">MySQL</font></p>
<p>&nbsp; select * from tablename limit position, counter</p>
<p>&nbsp;4.<font color="#ff0000">DB2</font></p>
<p>&nbsp; select * from (select *,rownumber() as ROW_NEXT from tablename) where ROW_NEXT between min and max&nbsp;</p>
</div>
<img src ="http://www.blogjava.net/i369/aggbug/183602.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/i369/" target="_blank">芦苇</a> 2008-03-04 09:14 <a href="http://www.blogjava.net/i369/articles/183602.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Oracle数据库的自动备份</title><link>http://www.blogjava.net/i369/articles/181450.html</link><dc:creator>芦苇</dc:creator><author>芦苇</author><pubDate>Fri, 22 Feb 2008 08:48:00 GMT</pubDate><guid>http://www.blogjava.net/i369/articles/181450.html</guid><wfw:comment>http://www.blogjava.net/i369/comments/181450.html</wfw:comment><comments>http://www.blogjava.net/i369/articles/181450.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/i369/comments/commentRss/181450.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/i369/services/trackbacks/181450.html</trackback:ping><description><![CDATA[<table cellspacing="0" cellpadding="0" width="98%" align="center" border="0">
    <tbody>
        <tr>
            <td class="cc" align="center" width="592" height="50">
            <div align="center"><strong><span class="dd style9"><strong style="color: black; background-color: #ffff66">Oracle</strong><strong style="color: black; background-color: #a0ffff">数据库</strong>的<strong style="color: black; background-color: #ff9999">自动备份</strong></span></strong></div>
            </td>
        </tr>
        <tr>
            <td background="../../images/end_bg2.gif" height="1">&nbsp;</td>
        </tr>
        <tr>
            <td align="center" bgcolor="#f5f5f5" height="22">&nbsp;</td>
        </tr>
        <tr>
            <td height="15">&nbsp;</td>
        </tr>
        <tr>
            <td class="bb" style="line-height: 150%">
            <p class="dd">&nbsp;</p>
            <p><font size="2">相信为数不少的</font><a href="http://www.myfaq.com.cn/System/index.html" target="_blank"><font color="#000000" size="2">系统</font></a><font size="2">管理员每天都在做着同一样的工作——对数据进行备份。一旦哪一天疏忽了，而这一天</font><a href="http://www.myfaq.com.cn/System/index.html" target="_blank"><font color="#000000" size="2">系统</font></a><font size="2">又恰恰发生了故障，需要进行数据恢复，那么此时就无能为力了。假如每天设定一个固定的时间，</font><a href="http://www.myfaq.com.cn/System/index.html" target="_blank"><font color="#000000" size="2">系统</font></a><font size="2">自动进行备份，那该多好啊！下面笔者结合实践经验，谈一谈UNIX环境下<strong style="color: black; background-color: #ffff66">Oracle</strong></font><a href="http://www.myfaq.com.cn/Dev/DataBase/index.html" target="_blank"><font color="#000000" size="2"><strong style="color: black; background-color: #a0ffff">数据库</strong></font></a><font size="2">的<strong style="color: black; background-color: #ff9999">自动备份</strong>，以起到抛砖引玉的作用。<br />
            　　<br />
            　　我们计划让</font><a href="http://www.myfaq.com.cn/Dev/DataBase/index.html" target="_blank"><font color="#000000" size="2"><strong style="color: black; background-color: #a0ffff">数据库</strong></font></a><font size="2">在晚上23点做export导出备份，在凌晨2点将备份</font><a href="http://www.myfaq.com.cn/Soft/Tools/File/index.html" target="_blank"><font color="#000000" size="2">文件</font></a><font size="2">拷贝到磁带上，在凌晨4点将备份</font><a href="http://www.myfaq.com.cn/Soft/Tools/File/index.html" target="_blank"><font color="#000000" size="2">文件</font></a><font size="2">拷贝到另一台UNIX机器上，为此我们可进行如下操作：<br />
            　　<br />
            　　<strong>一、导出<a href="http://www.myfaq.com.cn/Dev/DataBase/index.html" target="_blank"><font color="#000000"><strong style="color: black; background-color: #a0ffff">数据库</strong></font></a></strong><br />
            　　export命令将</font><a href="http://www.myfaq.com.cn/Dev/DataBase/index.html" target="_blank"><font color="#000000" size="2"><strong style="color: black; background-color: #a0ffff">数据库</strong></font></a><font size="2">中的数据备份成一个二进制</font><a href="http://www.myfaq.com.cn/Soft/Tools/File/index.html" target="_blank"><font color="#000000" size="2">文件</font></a><font size="2">，它通常有三种模式：用户模式、表模式和整个</font><a href="http://www.myfaq.com.cn/Dev/DataBase/index.html" target="_blank"><font color="#000000" size="2"><strong style="color: black; background-color: #a0ffff">数据库</strong></font></a><font size="2">模式。本文拟采用用户模式，备份之前，应先建立一个备份目录，以容纳备份</font><a href="http://www.myfaq.com.cn/Soft/Tools/File/index.html" target="_blank"><font color="#000000" size="2">文件</font></a><font size="2">，比如可建一个/backup目录。接着我们可在UNIX的<strong style="color: black; background-color: #ffff66">Oracle</strong>目录下（也可以是其它目录）分别建立两个</font><a href="http://www.myfaq.com.cn/Soft/Tools/File/index.html" target="_blank"><font color="#000000" size="2">文件</font></a><font size="2">ora—backup，tar—backup。需要说明的是，前一个</font><a href="http://www.myfaq.com.cn/Soft/Tools/File/index.html" target="_blank"><font color="#000000" size="2">文件</font></a><font size="2">需要对<strong style="color: black; background-color: #ffff66">Oracle</strong>的参数进行初始化，为了方便起见，我们不妨将初始化命令放到一个</font><a href="http://www.myfaq.com.cn/Soft/Tools/File/index.html" target="_blank"><font color="#000000" size="2">文件</font></a><font size="2">中（</font><a href="http://www.myfaq.com.cn/Soft/Tools/File/index.html" target="_blank"><font color="#000000" size="2">文件</font></a><font size="2">名姑且定为ora—env），再由第一个</font><a href="http://www.myfaq.com.cn/Soft/Tools/File/index.html" target="_blank"><font color="#000000" size="2">文件</font></a><font size="2">调用它。<br />
            　　<br />
            　　1. ora—env</font><a href="http://www.myfaq.com.cn/Soft/Tools/File/index.html" target="_blank"><font color="#000000" size="2">文件</font></a><font size="2">对<strong style="color: black; background-color: #ffff66">Oracle</strong>的参数进行初始化，其内容如下：<br />
            　　<br />
            　　<strong style="color: black; background-color: #ffff66">ORACLE</strong>—HOME=＄<strong style="color: black; background-color: #ffff66">ORACLE</strong>—HOME;export <strong style="color: black; background-color: #ffff66">ORACLE</strong>—HOME<br />
            　　<br />
            　　<strong style="color: black; background-color: #ffff66">ORACLE</strong>—SID=ora73;export <strong style="color: black; background-color: #ffff66">ORACLE</strong>—SID<br />
            　　<br />
            　　<strong style="color: black; background-color: #ffff66">ORACLE</strong>—TERM=sun;export <strong style="color: black; background-color: #ffff66">ORACLE</strong>—TERM<br />
            　　<br />
            　　LD—LIBRARY—PATH=＄<strong style="color: black; background-color: #ffff66">ORACLE</strong>—HOME/lib;export LD—LIBRARY—PATH<br />
            　　<br />
            　　ORA—NLS32=＄<strong style="color: black; background-color: #ffff66">ORACLE</strong>—HOME/ocommon/nls/admin/data;export ORA—NLS<br />
            　　<br />
            　　PATH=.:/usr/ccs/bin:/usr/ucb:＄<strong style="color: black; background-color: #ffff66">ORACLE</strong>—HOME/bin:＄PATH;export PATH<br />
            　　<br />
            　　DISPLAY=host1:0;export DISPLAY<br />
            　　<br />
            　　NLS—LANG=american—america.zhs16cgb231280;export NLS—LANG<br />
            　　<br />
            　　2. ora—backup</font><a href="http://www.myfaq.com.cn/Soft/Tools/File/index.html" target="_blank"><font color="#000000" size="2">文件</font></a><font size="2">对</font><a href="http://www.myfaq.com.cn/Dev/DataBase/index.html" target="_blank"><font color="#000000" size="2"><strong style="color: black; background-color: #a0ffff">数据库</strong></font></a><font size="2">做export导出，导出的</font><a href="http://www.myfaq.com.cn/Soft/Tools/File/index.html" target="_blank"><font color="#000000" size="2">文件</font></a><font size="2">名可以任意定，本文定为字母&#8220;xx&#8221;加当天日期，即假如当天日期是12月10号，则导出的</font><a href="http://www.myfaq.com.cn/Soft/Tools/File/index.html" target="_blank"><font color="#000000" size="2">文件</font></a><font size="2">名为&#8220;xx1210.dmp&#8221;，以区别于其它日期的备份</font><a href="http://www.myfaq.com.cn/Soft/Tools/File/index.html" target="_blank"><font color="#000000" size="2">文件</font></a><font size="2">。<br />
            　　<br />
            　　ora—backup</font><a href="http://www.myfaq.com.cn/Soft/Tools/File/index.html" target="_blank"><font color="#000000" size="2">文件</font></a><font size="2">内容：<br />
            　　<br />
            　　./<strong style="color: black; background-color: #ffff66">oracle</strong>/ora—env<br />
            　　<br />
            　　＃初始化<strong style="color: black; background-color: #ffff66">Oracle</strong></font><a href="http://www.myfaq.com.cn/Dev/DataBase/index.html" target="_blank"><font color="#000000" size="2"><strong style="color: black; background-color: #a0ffff">数据库</strong></font></a><br />
            <font size="2">　　<br />
            　　rq=&#8242;date ＋&#8243;％m％d&#8243; &#8242;<br />
            　　<br />
            　　＃把当天日期赋予变量rq<br />
            　　<br />
            　　rm /backup/<br />
            　　<br />
            　　＃ 清空 /backup目录<br />
            　　<br />
            　　exp test/test file=/backup/xx＄rq.dmp log=/backup/xx＄rq.log<br />
            　　<br />
            　　本命令用于在＄提示符下，导出test用户的数据（其口令亦为test），导出</font><a href="http://www.myfaq.com.cn/Soft/Tools/File/index.html" target="_blank"><font color="#000000" size="2">文件</font></a><font size="2">及日志均放在/backup目录下。<br />
            　　<br />
            　　<strong>二、磁带备份</strong><br />
            　　tar—backup</font><a href="http://www.myfaq.com.cn/Soft/Tools/File/index.html" target="_blank"><font color="#000000" size="2">文件</font></a><font size="2">将用export命令导出的数据</font><a href="http://www.myfaq.com.cn/Soft/Tools/File/index.html" target="_blank"><font color="#000000" size="2">文件</font></a><font size="2">拷贝到磁带上。<br />
            　　<br />
            　　tar—backup</font><a href="http://www.myfaq.com.cn/Soft/Tools/File/index.html" target="_blank"><font color="#000000" size="2">文件</font></a><font size="2">内容：<br />
            　　<br />
            　　tar rvf /dev/rmt/0n/backup/<br />
            　　<br />
            　　本命令可将/backup目录下当天产生的</font><a href="http://www.myfaq.com.cn/Soft/Tools/File/index.html" target="_blank"><font color="#000000" size="2">文件</font></a><font size="2">备份到磁带上。本</font><a href="http://www.myfaq.com.cn/Soft/Tools/File/index.html" target="_blank"><font color="#000000" size="2">文件</font></a><font size="2">中，tar命令使用了三个参数，其中r选项表示向磁带上拷入</font><a href="http://www.myfaq.com.cn/Soft/Tools/File/index.html" target="_blank"><font color="#000000" size="2">文件</font></a><font size="2">而不破坏磁带原来内容，v选项表示在拷贝过程中显示</font><a href="http://www.myfaq.com.cn/Soft/Tools/File/index.html" target="_blank"><font color="#000000" size="2">文件</font></a><font size="2">信息，f选项后面加上磁带设备名，指定</font><a href="http://www.myfaq.com.cn/Soft/Tools/File/index.html" target="_blank"><font color="#000000" size="2">文件</font></a><font size="2">向何处拷贝，n选项表示磁带机不倒带。/dev/rmt/0表示UNIX主机第一个磁带驱动器，同理，/dev/rmt/1则表示UNIX主机第二个磁带驱动器，依此类推。<br />
            　　<br />
            　　ora—env、ora—backup、tar—backup</font><a href="http://www.myfaq.com.cn/Soft/Tools/File/index.html" target="_blank"><font color="#000000" size="2">文件</font></a><font size="2">编写完成后，分别使用下述命令：<br />
            　　<br />
            　　chmod 755 ora—env<br />
            　　<br />
            　　chmod 755 ora—backup<br />
            　　<br />
            　　chmod 755 tar—backup<br />
            　　<br />
            　　这样，三个</font><a href="http://www.myfaq.com.cn/Soft/Tools/File/index.html" target="_blank"><font color="#000000" size="2">文件</font></a><font size="2">就都变成了可执行</font><a href="http://www.myfaq.com.cn/Soft/Tools/File/index.html" target="_blank"><font color="#000000" size="2">文件</font></a><font size="2">。<br />
            　　<br />
            　　<strong>三、异地备份</strong><br />
            　　我们知道，通常可用FTP命令在两台主机间传输数据，但一般是通过交互方式实现的，即需要手工输入目标主机的IP地址、用户名、口令等。显然，这不符合<strong style="color: black; background-color: #ff9999">自动备份</strong>的要求。所幸的是，我们可以通过编写一个.netrc的</font><a href="http://www.myfaq.com.cn/Soft/Tools/File/index.html" target="_blank"><font color="#000000" size="2">文件</font></a><font size="2">来达到目标。这一</font><a href="http://www.myfaq.com.cn/Soft/Tools/File/index.html" target="_blank"><font color="#000000" size="2">文件</font></a><font size="2">必须命名为.netrc，且必须存放在启动FTP命令的机器上的用户注册目录中，该</font><a href="http://www.myfaq.com.cn/Soft/Tools/File/index.html" target="_blank"><font color="#000000" size="2">文件</font></a><font size="2">的权限应禁止组内或其它用户进行读访问。这样，当用户使用FTP命令的时候，</font><a href="http://www.myfaq.com.cn/System/index.html" target="_blank"><font color="#000000" size="2">系统</font></a><font size="2">将会在该用户的注册目录中寻找.netrc</font><a href="http://www.myfaq.com.cn/Soft/Tools/File/index.html" target="_blank"><font color="#000000" size="2">文件</font></a><font size="2">，如果能够寻找到，将会首先执行该</font><a href="http://www.myfaq.com.cn/Soft/Tools/File/index.html" target="_blank"><font color="#000000" size="2">文件</font></a><font size="2">，否则，会交互式地提示用户输入用户名、口令等。<br />
            　　<br />
            　　在使用FTP命令之前，应先在另一台作备份用的UNIX机器上建一目录，以容纳备份</font><a href="http://www.myfaq.com.cn/Soft/Tools/File/index.html" target="_blank"><font color="#000000" size="2">文件</font></a><font size="2">，本文建的目录是/pub 。需要指出的是，为了加快备份速度，两台主机之间的传输速率应尽可能的高，最好位于同一局域网上。<br />
            　　<br />
            　　.netrc</font><a href="http://www.myfaq.com.cn/Soft/Tools/File/index.html" target="_blank"><font color="#000000" size="2">文件</font></a><font size="2">内容如下：<br />
            　　<br />
            　　machine host2<br />
            　　<br />
            　　＃ host2为作备份用的主机名<br />
            　　<br />
            　　login <strong style="color: black; background-color: #ffff66">oracle</strong><br />
            　　<br />
            　　＃<strong style="color: black; background-color: #ffff66">oracle</strong>为备份主机上的一个用户<br />
            　　<br />
            　　password <strong style="color: black; background-color: #ffff66">oracle</strong><br />
            　　<br />
            　　＃<strong style="color: black; background-color: #ffff66">oracle</strong>用户的口令为<strong style="color: black; background-color: #ffff66">oracle</strong><br />
            　　<br />
            　　macdef init<br />
            　　<br />
            　　＃定义一个名为init的宏，它将在自动注册进程的最后被执行<br />
            　　<br />
            　　bin<br />
            　　<br />
            　　＃</font><a href="http://www.myfaq.com.cn/Soft/Tools/File/index.html" target="_blank"><font color="#000000" size="2">文件</font></a><font size="2">的传输方式设为二进制<br />
            　　<br />
            　　lcd /backup<br />
            　　<br />
            　　＃ 进入本地工作目录/backup<br />
            　　<br />
            　　cd /pub<br />
            　　<br />
            　　＃ 进入备份主机目录/pub<br />
            　　<br />
            　　mput <br />
            　　<br />
            　　＃ 将/backup目录下的所有</font><a href="http://www.myfaq.com.cn/Soft/Tools/File/index.html" target="_blank"><font color="#000000" size="2">文件</font></a><font size="2">传输至备份主机<br />
            　　<br />
            　　bye<br />
            　　<br />
            　　＃退出FTP会话进程<br />
            　　<br />
            　　.netrc</font><a href="http://www.myfaq.com.cn/Soft/Tools/File/index.html" target="_blank"><font color="#000000" size="2">文件</font></a><font size="2">编写完成后，使用下述命令：<br />
            　　<br />
            　　chmod 600 .netrc<br />
            　　<br />
            　　这样，.netrc</font><a href="http://www.myfaq.com.cn/Soft/Tools/File/index.html" target="_blank"><font color="#000000" size="2">文件</font></a><font size="2">就只能被该用户所访问。<br />
            　　<br />
            　　<strong>四、启动备份进程</strong><br />
            　　Cron是一个永久进程，它由/etc/rc.local启动执行。Cron检查/var/spool/cron/crontabs/目录中的</font><a href="http://www.myfaq.com.cn/Soft/Tools/File/index.html" target="_blank"><font color="#000000" size="2">文件</font></a><font size="2">，找到所要执行的任务和执行任务的时间。<br />
            　　<br />
            　　Crontab</font><a href="http://www.myfaq.com.cn/Soft/Tools/File/index.html" target="_blank"><font color="#000000" size="2">文件</font></a><font size="2">的每一行由六个域(minutes、hours、day of month、month、day of week、 command)组成，域之间用空格或Tab分开，其中：<br />
            　　<br />
            　　minutes：分钟域，值的范围是0到59<br />
            　　<br />
            　　hours：小时域，值的范围是0到23<br />
            　　<br />
            　　day of month：日期，值的范围是1到31<br />
            　　<br />
            　　month：月份，值的范围是1到12<br />
            　　<br />
            　　day of week：星期，值的范围是0到6，星期日值为0<br />
            　　<br />
            　　command：所要运行的命令<br />
            　　<br />
            　　如果一个域是，表明命令可以在该域所有可能的取值范围内执行。<br />
            　　<br />
            　　如果一个域是由连</font><a href="http://www.myfaq.com.cn/Dev/Programme/VC/Str/index.html" target="_blank"><font color="#000000" size="2">字符</font></a><font size="2">隔开的两个数字，表明命令可以在两个数字之间的范围内执行（包括两个数字本身）。<br />
            　　<br />
            　　如果一个域是由逗号隔开的一系列值组成的，表明命令可以在这些值组成的范围内执行。<br />
            　　<br />
            　　如果日期域和星期域都有值，则这两个域都有效。<br />
            　　<br />
            　　现在，我们编写一个</font><a href="http://www.myfaq.com.cn/Soft/Tools/File/index.html" target="_blank"><font color="#000000" size="2">文件</font></a><font size="2">，用以启动<strong style="color: black; background-color: #ff9999">自动备份</strong>进程。值得注意的是，该</font><a href="http://www.myfaq.com.cn/Soft/Tools/File/index.html" target="_blank"><font color="#000000" size="2">文件</font></a><font size="2">只能在<strong style="color: black; background-color: #ffff66">Oracle</strong>用户名下用crontab －e 命令来编辑，否则将不会被定时执行，</font><a href="http://www.myfaq.com.cn/Soft/Tools/File/index.html" target="_blank"><font color="#000000" size="2">文件</font></a><font size="2">名定为<strong style="color: black; background-color: #ffff66">Oracle</strong>，</font><a href="http://www.myfaq.com.cn/Soft/Tools/File/index.html" target="_blank"><font color="#000000" size="2">文件</font></a><font size="2">将放在/var/spool/cron/crontabs 目录下。编辑完成后，可以在<strong style="color: black; background-color: #ffff66">Oracle</strong>的＄提示符下，用crontab －l命令来查看。<br />
            　　<br />
            　　<strong style="color: black; background-color: #ffff66">Oracle</strong></font><a href="http://www.myfaq.com.cn/Soft/Tools/File/index.html" target="_blank"><font color="#000000" size="2">文件</font></a><font size="2">内容：<br />
            　　<br />
            　　0 23    /<strong style="color: black; background-color: #ffff66">oracle</strong>/ora—backup<br />
            　　<br />
            　　＃ 每天23点对</font><a href="http://www.myfaq.com.cn/Dev/DataBase/index.html" target="_blank"><font color="#000000" size="2"><strong style="color: black; background-color: #a0ffff">数据库</strong></font></a><font size="2">执行备份<br />
            　　<br />
            　　0 2    /<strong style="color: black; background-color: #ffff66">oracle</strong>/tar—backup<br />
            　　<br />
            　　＃ 每天2点将</font><a href="http://www.myfaq.com.cn/Soft/Tools/File/index.html" target="_blank"><font color="#000000" size="2">文件</font></a><font size="2">备份到磁带上<br />
            　　<br />
            　　0 4    ftp －i host2<br />
            　　<br />
            　　＃ 每天4点将</font><a href="http://www.myfaq.com.cn/Soft/Tools/File/index.html" target="_blank"><font color="#000000" size="2">文件</font></a><font size="2">备份到另一台主机上<br />
            　　<br />
            　　经过以上的操作后，</font><a href="http://www.myfaq.com.cn/System/index.html" target="_blank"><font color="#000000" size="2">系统</font></a><font size="2">每天晚上将自动产生一个备份，并且自动将备份</font><a href="http://www.myfaq.com.cn/Soft/Tools/File/index.html" target="_blank"><font color="#000000" size="2">文件</font></a><font size="2">分别拷贝到磁带上和另一台主机上。</font><a href="http://www.myfaq.com.cn/System/index.html" target="_blank"><font color="#000000" size="2">系统</font></a><font size="2">管理员需要做的是，隔几天换一盘磁带（更换磁带的周期取决于备份</font><a href="http://www.myfaq.com.cn/Soft/Tools/File/index.html" target="_blank"><font color="#000000" size="2">文件</font></a><font size="2">的大小和磁带的容量）和清理备份目录。这样，他们就可以从备份数据的繁琐中解脱出来，去做其它更有意义的工作。而</font><a href="http://www.myfaq.com.cn/Dev/DataBase/index.html" target="_blank"><font color="#000000" size="2"><strong style="color: black; background-color: #a0ffff">数据库</strong></font></a><font size="2">既实现了磁带备份，又实现了异地备份，相应的安全性也大大提高了。</font></p>
            <p><font size="2">转自：<a href="http://www.myfaq.com.cn/A/2004-07-07/85801.html">http://www.myfaq.com.cn/A/2004-07-07/85801.html</a></font></p>
            </td>
        </tr>
    </tbody>
</table>
<p><strong><font color="#0000ff">实现脚本</font></strong><br />
rem #=========================================================================<br />
rem # Purpose:exp Oracle DB ZYTK30 to file ZYTK30_YYYYMMDDHHMM.dmp,<br />
rem #&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; and Delete the file,7 days ago created <br />
rem # Author :Comer Chu, 2006</p>
<p>rem # History:<br />
rem # Note&nbsp;&nbsp; :erveryday excute this script by windows task schedule&nbsp; <br />
rem #=========================================================================</p>
<p>@echo off<br />
rem 1#---获得当前日期和7天前日期，date的格式 "YYYY-MM-DD"----------<br />
set dt=%date:~0,10%<br />
set i=1</p>
<p>:forok<br />
if %i%==1 goto i01<br />
if %i%==2 goto i02<br />
if %i%==3 goto i03<br />
if %i%==4 goto i04<br />
if %i%==5 goto i05<br />
if %i%==6 goto i06<br />
if %i%==7 goto i07</p>
<p>:i01<br />
set i=2<br />
goto nextok<br />
:i02<br />
set i=3<br />
goto nextok<br />
:i03<br />
set i=4<br />
goto nextok<br />
:i04<br />
set i=5<br />
goto nextok<br />
:i05<br />
set i=6<br />
goto nextok<br />
:i06<br />
set i=7<br />
goto nextok<br />
:i07<br />
set i=8<br />
goto nextok</p>
<p>:nextok<br />
set dy=%dt:~0,4%<br />
set dm=%dt:~5,2%<br />
set dd=%dt:~8,2%</p>
<p>if %dm%%dd%==0101 goto L01<br />
if %dm%%dd%==0201 goto L02<br />
if %dm%%dd%==0301 goto L07<br />
if %dm%%dd%==0401 goto L02<br />
if %dm%%dd%==0501 goto L04<br />
if %dm%%dd%==0601 goto L02<br />
if %dm%%dd%==0701 goto L04<br />
if %dm%%dd%==0801 goto L02<br />
if %dm%%dd%==0901 goto L02<br />
if %dm%%dd%==1001 goto L05<br />
if %dm%%dd%==1101 goto L03<br />
if %dm%%dd%==1201 goto L06</p>
<p>if %dd%==02 goto L10<br />
if %dd%==03 goto L10<br />
if %dd%==04 goto L10<br />
if %dd%==05 goto L10<br />
if %dd%==06 goto L10<br />
if %dd%==07 goto L10<br />
if %dd%==08 goto L10<br />
if %dd%==09 goto L10<br />
if %dd%==10 goto L11<br />
set /A dd=dd-1<br />
set dt=%dy%-%dm%-%dd%<br />
goto END<br />
:L10<br />
set /A dd=%dd:~1,1%-1<br />
set dt=%dy%-%dm%-0%dd%<br />
goto END<br />
:L11<br />
set dt=%dy%-%dm%-09<br />
goto END</p>
<p>:L02<br />
set /A dm=%dm:~1,1%-1<br />
set dt=%dy%-0%dm%-31<br />
goto END<br />
:L04<br />
set /A dm=dm-1<br />
set dt=%dy%-0%dm%-30<br />
goto END</p>
<p>:L05<br />
set dt=%dy%-09-30<br />
goto END<br />
:L03<br />
set dt=%dy%-10-31<br />
goto END<br />
:L06<br />
set dt=%dy%-11-30<br />
goto END<br />
:L01<br />
set /A dy=dy-1<br />
set dt=%dy%-12-31<br />
goto END</p>
<p>:L07<br />
set /A "dd=dy%%4"<br />
if not %dd%==0 goto L08<br />
set /A "dd=dy%%100"<br />
if not %dd%==0 goto L09<br />
set /A "dd=dy%%400"<br />
if %dd%==0 goto L09<br />
:L08<br />
set dt=%dy%-02-28<br />
goto END<br />
:L09<br />
set dt=%dy%-02-29<br />
goto END</p>
<p>:END<br />
if %i%==2 goto forok<br />
if %i%==3 goto forok<br />
if %i%==4 goto forok<br />
if %i%==5 goto forok<br />
if %i%==6 goto forok<br />
if %i%==7 goto forok<br />
if %i%==8 goto db</p>
<p>:db<br />
rem 2#---备份oracle数据到本机，并且只备份表空间，前提本机正确配置了Oracle的客户端，否则exp无法执行！<br />
rem td like 20060827183200<br />
set td=%Date:~0,4%%Date:~5,2%%Date:~8,2%%Time:~0,2%%Time:~3,2%%Time:~6,2%<br />
e:\oracleback<br />
exp <a href="mailto:user/password@zytk30">user/password@zytk30</a> tablespaces=(ZYTK30_AC,ZYTK30_OP,ZYTK30_ID,ZYTK30_BAK) file=e:\OracleBack\ZYTK30_%td%.dmp log=e:\OracleBack\expZYTK30.Log buffer=800000<br />
rar a ZYTK30_%td%.rar ZYTK30_%td%.dmp</p>
<p>rem set dt to format "yyyymmdd"<br />
set dt=%dt:~0,4%%dt:~5,2%%dt:~8,2%<br />
rem 3#---删除7天前的备份文件---------------------------------------------------------<br />
del e:\OracleBack\ZYTK30_%dt%*.rar</p>
<p>rem 4#---删除当天dmp备份文件--------------------------------------------------------<br />
del e:\OracleBack\ZYTK30_%td%*.dmp</p>
<p><font color="#0000ff"><strong>定时任务<br />
</strong></font>以上内容保存为exp_ZYTK30.bat，再使用windows自带的任务计划来计划程序每天自动去备份数据了<br />
具体步骤：控制面板-\任务计划-\添加任务计划，选择每天，选择exp_ZYTK30.bat就ok了。</p>
<p><strong><font color="#0000ff">说明<br />
</font></strong>上面是保留备份最近7天的数据，每天一个（当然也可以多个，设置任务计划即可）。你可以修改上面的代码到最近8、9甚至n天</p>
<p>比如：修改成保留8天的备份<br />
在if %i%==7 goto i07 下增加 <br />
if %i%==8 goto i08<br />
:i07<br />
set i=8</p>
<p>在goto nextok 下增加 <br />
:i08<br />
set i=9<br />
goto nextok </p>
<p>将if %i%==8 goto mdb 改为 <br />
if %i%==8 goto forok<br />
if %i%==9 goto mdb</p>
<p>依次类推到n天。也可以针对文件夹的删除，稍作变动即可。<br />
</p>
<img src ="http://www.blogjava.net/i369/aggbug/181450.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/i369/" target="_blank">芦苇</a> 2008-02-22 16:48 <a href="http://www.blogjava.net/i369/articles/181450.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>在PL/SQL 开发中调试存储过程和函数的一般性方法 </title><link>http://www.blogjava.net/i369/articles/164185.html</link><dc:creator>芦苇</dc:creator><author>芦苇</author><pubDate>Fri, 30 Nov 2007 02:06:00 GMT</pubDate><guid>http://www.blogjava.net/i369/articles/164185.html</guid><wfw:comment>http://www.blogjava.net/i369/comments/164185.html</wfw:comment><comments>http://www.blogjava.net/i369/articles/164185.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/i369/comments/commentRss/164185.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/i369/services/trackbacks/164185.html</trackback:ping><description><![CDATA[<span style="font-size: 13pt"><font id="zoom">在PL/<a href="http://www.e2web.cn/search/index.aspx?q=SQL">SQL</a> 开发中调试<a href="http://www.e2web.cn/search/index.aspx?q=%B4%E6%B4%A2%B9%FD%B3%CC">存储过程</a>和<a href="http://www.e2web.cn/search/index.aspx?q=%BA%AF%CA%FD">函数</a>的一般性方法<br />
摘要: <a href="http://www.e2web.cn/search/list.aspx?classname=Oracle">Oracle</a> 在PLSQL中提供的强大特性使得<a href="http://www.e2web.cn/search/index.aspx?q=%CA%FD%BE%DD%BF%E2">数据库</a>开发人员可以在数据库端完成功能足够复杂的任务, 本文将结合Oracle提供的相关程序包(package)以及一个非常优秀的第三方开发工具来介绍在PLSQL中开发及调试存储过程的方法，当然也适用于函数。<br />
<br />
版权声明: 本文可以任意转载，转载时请务必以超链接形式标明文章原始出处和作者信息。<br />
原文出处: http://www.aiview.com/notes/ora_using_proc.htm<br />
作者: 张洋 Alex_doesAThotmail.com<br />
最后更新: 2003-8-2<br />
　目录 准备工作 从一个最简单的存储过程开始 调试存储过程 在存储过程中写日志文件 捕获违例 <br />
　 <br />
Oracle 在PLSQL中提供的强大特性使得数据库开发人员可以在数据库端完成功能足够复杂的任务, 本文将结合Oracle提供的相关程序包(package)以及一个非常优秀的第三方开发工具来介绍在PLSQL中开发及调试存储过程的方法，当然也适用于函数。<br />
<br />
本文所采用的软件版本和环境:<br />
<a href="http://www.e2web.cn/search/index.aspx?q=%B7%FE%CE%F1%C6%F7">服务器</a>: Oracle 8.1.2 for <a href="http://www.e2web.cn/search/list.aspx?classname=Solaris">Solaris</a> 8<br />
PL/SQL Developer 4.5<br />
准备工作<br />
在开始之前, 假设您已经安装好了Oracle的数据库服务, 并已经建立数据库, 设置好监听程序, 以允许客户端进行连接; 同时您已经拥有了一台设置好本地Net服务名的开发客户机, 并已经安装好PL/SQL Developer开发工具的以上版本或者更新.<br />
<br />
在下面的示例代码中,我们使用Oracle数据库默认提供的示例表 scott.dept 和 scott.emp. 建表的语句如下：<br />
<br />
create table SCOTT.DEPT<br />
(<br />
DEPTNO NUMBER(2) not null,<br />
DNAME VARCHAR2(14),<br />
LOC VARCHAR2(13)<br />
)<br />
<br />
create table SCOTT.EMP<br />
(<br />
EMPNO NUMBER(4) not null,<br />
ENAME VARCHAR2(10),<br />
JOB VARCHAR2(9),<br />
MGR NUMBER(4),<br />
HIREDATE DATE,<br />
SAL NUMBER(7,2),<br />
COMM NUMBER(7,2),<br />
DEPTNO NUMBER(2)<br />
)<br />
从一个最简单的存储过程开始<br />
我们现在需要编写一个存储过程, 输入一个部门的编号, 要求取得属于这个部门的所有员工信息, 包括员工编号和姓名. 员工的信息通过一个cursor返回给<a href="http://www.e2web.cn/search/index.aspx?q=%D3%A6%D3%C3%B3%CC%D0%F2">应用程序</a>.<br />
<br />
create or replace procedure usp_getEmpByDept(<br />
in_deptNo in number,<br />
out_curEmp out pkg_const.REF_CURSOR&nbsp;<br />
) as<br />
begin<br />
open curEmp for&nbsp;<br />
select empno,<br />
ename<br />
from scott.emp<br />
where deptno = in_deptNo;<br />
<br />
end usp_getEmpByDept;<br />
<br />
上面我们定义了两个参数, 其中第二个参数需要利用cursor返回员工信息, PLSQL中提供了REF CURSOR的数据类型, 可以采用两种方式进行定义, 一种是强类型,一种是弱类型, 前者在定义时指定cursor返回的数据类型, 后者可以不指定, 由数据库根据查询语句进行动态绑定.<br />
<br />
在使用前必须首先使用TYPE关键字进行定义, 我们把数据类型REF_CURSOR定义在自定义的程序包中: pkg_const<br />
<br />
create or replace package pkg_const as<br />
type REF_CURSOR is ref cursor;<br />
<br />
end pkg_const;<br />
<br />
注意: 这个包需要在创建上面的存储过程之前被编译, 因为存储过程用到了包中定义的数据类型.<br />
调试存储过程<br />
使用PL/SQL Developer 登录数据库, 用户名scott, 密码默认为: tiger. 将包和存储过程分别编译, 然后在左侧浏览器的procedure栏目下找到新建的存储过程, 点击右键, 选择"Test"/"测试", 在下面添好需要输入的参数值, 按快捷键F8直接运行存储过程, 执行完成之后, 可以点开返回参数旁边的按钮查看结果集.<br />
<br />
如果存储过程内部语句较复杂, 可以按F9进入存储过程进行跟踪调试. PL/SQL Developer提供与通用开发工具类似的跟踪调试功能, 分为step、step over、step out 等多种方式， 对于变量也可进行trace或者手动赋值。<br />
在存储过程中写日志文件<br />
以上方法可以在开发阶段对编写和调试存储过程提供最大限度的方便，但为了在系统测试或者生产环境中确认我们的代码是否正常工作时，就需要记录log。<br />
<br />
PLSQL提供了一个UTL_FILE包，通过定义UTL_FILE包中的FILE_TYPE类型，可以获得一个文件句柄，通过此句柄可以实现一般的文件操作功能。但默认的数据库参数是不允许使用UTL_FILE包的，需要手动进行配置，使用GUI的管理工具或者手工编辑INIT.ORA文件，找到 "utl_file_dir" 参数，如果没有，则添加一行，修改成如下：<br />
<br />
utl_file_dir=@#/usr/tmp@#<br />
<br />
或者<br />
<br />
utl_file_dir=*<br />
<br />
第一种方式限定了在UTL_FILE包中可以存取的目录，第二种方式则不进行限定。无论哪种方式，都要保证运行数据库实例的用户，一般是oracle，拥有此目录的存取权限，否则在使用包的过程中会报出错误信息。<br />
<br />
注意等号左右不要留空格，可能会引起解析错误，导致设置无效。<br />
<br />
下面在上面的存储过程中加入记录log的代码：<br />
<br />
create or replace procedure usp_getEmpByDept(<br />
in_deptNo in number,<br />
out_curEmp out pkg_const.REF_CURSOR&nbsp;<br />
) as<br />
fi utl_file.file_type;<br />
<br />
begin<br />
if( pkg_const.DEBUG ) then&nbsp;<br />
fi := utl_file.fopen( pkg_const.LOG_PATH, to_char( sysdate, @#yyyymmdd@# ) || @#.log@#, @#a@# );<br />
utl_file.put_line( fi, @# ****** calling usp_getEmpByDept begin at @# || to_char( sysdate, @#hh24:mi:ss mm-dd-yyyy@# ) || @# ******@# );<br />
utl_file.put_line( fi, @# INPUT:@# );<br />
utl_file.put_line( fi, @# in_chID =&gt; @# || in_chID );<br />
end if;<br />
<br />
open curEmp for&nbsp;<br />
select empno,<br />
ename<br />
from scott.emp<br />
where deptno = in_deptNo;<br />
<br />
if( pkg_const.DEBUG ) then&nbsp;<br />
utl_file.put_line( fi, @# RETURN:@# );<br />
utl_file.put_line( fi, @# out_curEmp: unknown@# );<br />
utl_file.put_line( fi, @# ****** usp_getEmpByDept end at @# || to_char( sysdate, @#hh24:mi:ss mm-dd-yyyy@# ) || @# ******@# );<br />
utl_file.new_line( fi, 1 );<br />
utl_file.fflush( fi );<br />
utl_file.fclose( fi );<br />
end if;<br />
<br />
exception<br />
when others then<br />
<br />
if( pkg_const.DEBUG ) then&nbsp;<br />
if( utl_file.is_open( fi )) then<br />
utl_file.put_line( fi, @# ERROR:@# );<br />
utl_file.put_line( fi, @# sqlcode = @# || sqlcode );<br />
utl_file.put_line( fi, @# sqlerrm = @# || sqlerrm );<br />
utl_file.put_line( fi, @# ****** usp_getEmpByDept end at @# || to_char( sysdate, @#hh24:mi:ss mm-dd-yyyy@# ) || @# ******@# );<br />
utl_file.new_line( fi, 1 );<br />
utl_file.fflush( fi );<br />
utl_file.fclose( fi );<br />
end if;<br />
end if;<br />
<br />
/* Raise the exception for caller. */<br />
raise_application_error( -20001, sqlcode || @#|@# || sqlerrm );<br />
<br />
end usp_getEmpByDept;<br />
<br />
在上面的代码中，我们又引用了两个新的常量：<br />
<br />
DEBUG<br />
LOG_PATH<br />
<br />
分别定义了调试开关参数和文件路径参数，对此，我们需要修改我们前面定义的程序包：<br />
<br />
create or replace package pkg_const as<br />
type REF_CURSOR is ref cursor;<br />
<br />
DEBUG constant boolean := true;<br />
LOG_PATH constant varchar2(256) := @#/usr/tmp/db@#;<br />
<br />
end pkg_const;<br />
<br />
在代码块的起始处，将输入参数的名称与值成对的记入log文件，在代码块的正常退出部分，将输出参数的名称和数值也成对的记录下来，如果程序非正常退出，则在exception 的处理部分，把错误代码及错误信息写入log文件。一般使用这些信息就可以较迅速的找出程序运行中出现的大部分错误。<br />
<br />
注意：如果返回参数的类型是cursor，是无法在存储过程内部将返回的结果集一条一条写入log文件的，此时应当结合在调用程序中记录的log信息，下面具体分析一下上述代码：<br />
<br />
fopen() 函数使用给定的路径和文件名，新建文件或者打开已有的文件，这取决于最后一个参数, 当使用@#a@#作为参数时，如果给定的文件不存在，则以此文件名新建文件，并以写@#w@#方式打开，返回一个文件句柄。<br />
<br />
上面代码以天为单位建立日志文件，并且，不同存储过程之间共享log文件，这种方式的优点是可能通过查看log文件追溯出程序的调用顺序和逻辑。实际应用中，应根据不同的需求，具体分析，可以使用更复杂的log文件生成策略。<br />
<br />
put_line() 函数用于写入字符到文件，并在字符串的结尾加入换行符，若不想换行，使用put()函数。<br />
<br />
new_line() 函数用于生成指定数目的空行，上面对文件的修改写在一个缓冲区内，执行fflush() 将立即将buffer中的内容写入文件，当你希望在文件还未关闭之前就需要读取已经作出的改变时，调用此函数。<br />
<br />
is_open() 函数用于判断一个文件句柄的状态，最后用完一定记得把打开的文件关闭，调用fclose() 函数，并且应把这个语句加入exception的处理中，防止过程非正常退出时留下未关闭的文件句柄。<br />
捕获违例<br />
在PLSQL中，你可以通过两个内建的函数sqlcode 和sqlerrm 来找出发生了哪类错误并且获得详细的message信息，在内部违例发生时，sqlcode返回从-1至－20000之间的一个错误号，但有一个例外，仅当内部违例no_data_found 发生时，才会返回一个正数 100。当用户自定义的违例发生时，sqlcode返回＋1，除非用户使用 pragma EXCEPTION_INIT 将自定义违例绑定一个自定义的错误号。当没有任何违例抛出时，sqlcode返回0。<br />
<br />
下面是一个简单的捕获违例的例子：<br />
<br />
declare<br />
i number(3);<br />
begin<br />
select 100/0 into i from dual;<br />
<br />
exception<br />
when zero_divide then<br />
...<br />
end;<br />
<br />
在上面的exception 中我们使用others 关键字捕获所有未明确指定的违例，并进行记录log处理，同时我们必须在做完这些处理之后，把违例再次抛出给调用程序，调用函数：<br />
raise_application_error()，此函数向调用程序返回一个用户自定义的错误号码和错误信息，第一个参数指定一个错误号码，由用户自行定义，但必须限定在-20000至－20999之间，避免与Oracle内部定义exception的错误号码冲突，第二个参数需要返回一个字符串，这里我们使用它返回我们上面捕获的错误号码和错误描述。<br />
<br />
注意：通过raise_application_error()函数抛出的违例已经不是开始在程序块内部捕获的内部违例，而是由用户自己定义的。<br />
</font></span>
<img src ="http://www.blogjava.net/i369/aggbug/164185.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/i369/" target="_blank">芦苇</a> 2007-11-30 10:06 <a href="http://www.blogjava.net/i369/articles/164185.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C3P0连接池详细配置  </title><link>http://www.blogjava.net/i369/articles/151043.html</link><dc:creator>芦苇</dc:creator><author>芦苇</author><pubDate>Mon, 08 Oct 2007 05:55:00 GMT</pubDate><guid>http://www.blogjava.net/i369/articles/151043.html</guid><wfw:comment>http://www.blogjava.net/i369/comments/151043.html</wfw:comment><comments>http://www.blogjava.net/i369/articles/151043.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/i369/comments/commentRss/151043.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/i369/services/trackbacks/151043.html</trackback:ping><description><![CDATA[<h1 style="text-align: center"><span style="color: rgb(255,0,255)">&nbsp;</span><a title="永久链接：C3P0连接池详细配置 " style="color: rgb(255,0,255)" href="http://msq.javaeye.com/blog/60387">C3P0连接池详细配置</a>(转载)</h1>
<p>&lt;c3p0-config&gt; <br />
&lt;default-config&gt; <br />
&lt;!--当连接池中的连接耗尽的时候c3p0一次同时获取的连接数。Default: 3 --&gt; <br />
&lt;property name="acquireIncrement"&gt;3&lt;/property&gt; <br />
<br />
&lt;!--定义在从数据库获取新连接失败后重复尝试的次数。Default: 30 --&gt; <br />
&lt;property name="acquireRetryAttempts"&gt;30&lt;/property&gt; <br />
<br />
&lt;!--两次连接中间隔时间，单位毫秒。Default: 1000 --&gt; <br />
&lt;property name="acquireRetryDelay"&gt;1000&lt;/property&gt; <br />
<br />
&lt;!--连接关闭时默认将所有未提交的操作回滚。Default: false --&gt; <br />
&lt;property name="autoCommitOnClose"&gt;false&lt;/property&gt; <br />
<br />
&lt;!--c3p0将建一张名为Test的空表，并使用其自带的查询语句进行测试。如果定义了这个参数那么 <br />
属性preferredTestQuery将被忽略。你不能在这张Test表上进行任何操作，它将只供c3p0测试 <br />
使用。Default: null--&gt; <br />
&lt;property name="automaticTestTable"&gt;Test&lt;/property&gt; <br />
<br />
&lt;!--获取连接失败将会引起所有等待连接池来获取连接的线程抛出异常。但是数据源仍有效 <br />
保留，并在下次调用getConnection()的时候继续尝试获取连接。如果设为true，那么在尝试 <br />
获取连接失败后该数据源将申明已断开并永久关闭。Default: false--&gt; <br />
&lt;property name="breakAfterAcquireFailure"&gt;false&lt;/property&gt; <br />
<br />
&lt;!--当连接池用完时客户端调用getConnection()后等待获取新连接的时间，超时后将抛出 <br />
SQLException,如设为0则无限期等待。单位毫秒。Default: 0 --&gt; <br />
&lt;property name="checkoutTimeout"&gt;100&lt;/property&gt; <br />
<br />
&lt;!--通过实现ConnectionTester或QueryConnectionTester的类来测试连接。类名需制定全路径。 <br />
Default: com.mchange.v2.c3p0.impl.DefaultConnectionTester--&gt; <br />
&lt;property name="connectionTesterClassName"&gt;&lt;/property&gt; <br />
<br />
&lt;!--指定c3p0 libraries的路径，如果（通常都是这样）在本地即可获得那么无需设置，默认null即可 <br />
Default: null--&gt; <br />
&lt;property name="factoryClassLocation"&gt;null&lt;/property&gt; <br />
<br />
&lt;!--Strongly disrecommended. Setting this to true may lead to subtle and bizarre bugs. <br />
（文档原文）作者强烈建议不使用的一个属性--&gt; <br />
&lt;property name="forceIgnoreUnresolvedTransactions"&gt;false&lt;/property&gt; <br />
<br />
&lt;!--每60秒检查所有连接池中的空闲连接。Default: 0 --&gt; <br />
&lt;property name="idleConnectionTestPeriod"&gt;60&lt;/property&gt; <br />
<br />
&lt;!--初始化时获取三个连接，取值应在minPoolSize与maxPoolSize之间。Default: 3 --&gt; <br />
&lt;property name="initialPoolSize"&gt;3&lt;/property&gt; <br />
<br />
&lt;!--最大空闲时间,60秒内未使用则连接被丢弃。若为0则永不丢弃。Default: 0 --&gt; <br />
&lt;property name="maxIdleTime"&gt;60&lt;/property&gt; <br />
<br />
&lt;!--连接池中保留的最大连接数。Default: 15 --&gt; <br />
&lt;property name="maxPoolSize"&gt;15&lt;/property&gt; <br />
<br />
&lt;!--JDBC的标准参数，用以控制数据源内加载的PreparedStatements数量。但由于预缓存的statements <br />
属于单个connection而不是整个连接池。所以设置这个参数需要考虑到多方面的因素。 <br />
如果maxStatements与maxStatementsPerConnection均为0，则缓存被关闭。Default: 0--&gt; <br />
&lt;property name="maxStatements"&gt;100&lt;/property&gt; <br />
<br />
&lt;!--maxStatementsPerConnection定义了连接池内单个连接所拥有的最大缓存statements数。Default: 0 --&gt; <br />
&lt;property name="maxStatementsPerConnection"&gt;&lt;/property&gt; <br />
<br />
&lt;!--c3p0是异步操作的，缓慢的JDBC操作通过帮助进程完成。扩展这些操作可以有效的提升性能 <br />
通过多线程实现多个操作同时被执行。Default: 3--&gt; <br />
&lt;property name="numHelperThreads"&gt;3&lt;/property&gt; <br />
<br />
&lt;!--当用户调用getConnection()时使root用户成为去获取连接的用户。主要用于连接池连接非c3p0 <br />
的数据源时。Default: null--&gt; <br />
&lt;property name="overrideDefaultUser"&gt;root&lt;/property&gt; <br />
<br />
&lt;!--与overrideDefaultUser参数对应使用的一个参数。Default: null--&gt; <br />
&lt;property name="overrideDefaultPassword"&gt;password&lt;/property&gt; <br />
<br />
&lt;!--密码。Default: null--&gt; <br />
&lt;property name="password"&gt;&lt;/property&gt; <br />
<br />
&lt;!--定义所有连接测试都执行的测试语句。在使用连接测试的情况下这个一显著提高测试速度。注意： <br />
测试的表必须在初始数据源的时候就存在。Default: null--&gt; <br />
&lt;property name="preferredTestQuery"&gt;select id from test where id=1&lt;/property&gt; <br />
<br />
&lt;!--用户修改系统配置参数执行前最多等待300秒。Default: 300 --&gt; <br />
&lt;property name="propertyCycle"&gt;300&lt;/property&gt; <br />
<br />
&lt;!--因性能消耗大请只在需要的时候使用它。如果设为true那么在每个connection提交的 <br />
时候都将校验其有效性。建议使用idleConnectionTestPeriod或automaticTestTable <br />
等方法来提升连接测试的性能。Default: false --&gt; <br />
&lt;property name="testConnectionOnCheckout"&gt;false&lt;/property&gt; <br />
<br />
&lt;!--如果设为true那么在取得连接的同时将校验连接的有效性。Default: false --&gt; <br />
&lt;property name="testConnectionOnCheckin"&gt;true&lt;/property&gt; <br />
<br />
&lt;!--用户名。Default: null--&gt; <br />
&lt;property name="user"&gt;root&lt;/property&gt; <br />
<br />
&lt;!--早期的c3p0版本对JDBC接口采用动态反射代理。在早期版本用途广泛的情况下这个参数 <br />
允许用户恢复到动态反射代理以解决不稳定的故障。最新的非反射代理更快并且已经开始 <br />
广泛的被使用，所以这个参数未必有用。现在原先的动态反射与新的非反射代理同时受到 <br />
支持，但今后可能的版本可能不支持动态反射代理。Default: false--&gt; <br />
&lt;property name="usesTraditionalReflectiveProxies"&gt;false&lt;/property&gt;</p>
<p>&lt;property name="automaticTestTable"&gt;con_test&lt;/property&gt; <br />
&lt;property name="checkoutTimeout"&gt;30000&lt;/property&gt; <br />
&lt;property name="idleConnectionTestPeriod"&gt;30&lt;/property&gt; <br />
&lt;property name="initialPoolSize"&gt;10&lt;/property&gt; <br />
&lt;property name="maxIdleTime"&gt;30&lt;/property&gt; <br />
&lt;property name="maxPoolSize"&gt;25&lt;/property&gt; <br />
&lt;property name="minPoolSize"&gt;10&lt;/property&gt; <br />
&lt;property name="maxStatements"&gt;0&lt;/property&gt; <br />
&lt;user-overrides user="swaldman"&gt; <br />
&lt;/user-overrides&gt; <br />
&lt;/default-config&gt; <br />
&lt;named-config name="dumbTestConfig"&gt; <br />
&lt;property name="maxStatements"&gt;200&lt;/property&gt; <br />
&lt;user-overrides user="poop"&gt; <br />
&lt;property name="maxStatements"&gt;300&lt;/property&gt; <br />
&lt;/user-overrides&gt; <br />
&lt;/named-config&gt; <br />
&lt;/c3p0-config&gt;</p>
原地址：http://msq.javaeye.com/blog/60387<br />
<br />
<img src ="http://www.blogjava.net/i369/aggbug/151043.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/i369/" target="_blank">芦苇</a> 2007-10-08 13:55 <a href="http://www.blogjava.net/i369/articles/151043.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>sql server系统表详细说明 </title><link>http://www.blogjava.net/i369/articles/149448.html</link><dc:creator>芦苇</dc:creator><author>芦苇</author><pubDate>Sat, 29 Sep 2007 01:41:00 GMT</pubDate><guid>http://www.blogjava.net/i369/articles/149448.html</guid><wfw:comment>http://www.blogjava.net/i369/comments/149448.html</wfw:comment><comments>http://www.blogjava.net/i369/articles/149448.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/i369/comments/commentRss/149448.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/i369/services/trackbacks/149448.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: sysaltfiles &nbsp;主数据库 保存数据库的文件 syscharsets &nbsp;主数据库字符集与排序顺序sysconfigures 主数据库 配置选项&nbsp;syscurconfigs 主数据库当前配置选项&nbsp; sysdatabases 主数据库服务器中的数据库&nbsp; syslanguages 主数据库语言&nbsp; syslogin...&nbsp;&nbsp;<a href='http://www.blogjava.net/i369/articles/149448.html'>阅读全文</a><img src ="http://www.blogjava.net/i369/aggbug/149448.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/i369/" target="_blank">芦苇</a> 2007-09-29 09:41 <a href="http://www.blogjava.net/i369/articles/149448.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>oracle字符集理解</title><link>http://www.blogjava.net/i369/articles/148004.html</link><dc:creator>芦苇</dc:creator><author>芦苇</author><pubDate>Tue, 25 Sep 2007 02:53:00 GMT</pubDate><guid>http://www.blogjava.net/i369/articles/148004.html</guid><wfw:comment>http://www.blogjava.net/i369/comments/148004.html</wfw:comment><comments>http://www.blogjava.net/i369/articles/148004.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/i369/comments/commentRss/148004.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/i369/services/trackbacks/148004.html</trackback:ping><description><![CDATA[<div>oracle字符集理解：</div>
<div>&nbsp;</div>
<div><strong>一．引言</strong>
<p><strong>&nbsp;&nbsp;&nbsp; </strong>ORACLE数据库字符集，即Oracle全球化支持(Globalization Support)，或即国家语言支持（NLS）其作用是用本国语言和格式来存储、处理和检索数据。利用全球化支持，ORACLE为用户提供自己熟悉的数据库母语环境，诸如日期格式、数字格式和存储序列等。Oracle可以支持多种语言及字符集，其中oracle8i支持48种语言、76个国家地域、229种字符集，而oracle9i则支持57种语言、88个国家地域、235种字符集。由于oracle字符集种类多，且在存储、检索、迁移oracle数据时多个环节与字符集的设置密切相关，因此在实际的应用中，数据库开发和管理人员经常会遇到有关oracle字符集方面的问题。本文通过以下几个方面阐述，对oracle字符集做简要分析</p>
<p><strong>二．字符集基本知识</strong></p>
<p><strong>2.1字符集<br />
</strong>&nbsp;&nbsp;&nbsp; 实质就是按照一定的字符编码方案，对一组特定的符号，分别赋予不同数值编码的集合。Oracle数据库最早支持的编码方案是US7ASCII。<br />
&nbsp;&nbsp;&nbsp; Oracle的字符集命名遵循以下命名规则:<br />
&nbsp;&nbsp;&nbsp; &lt;Language&gt;&lt;bit size&gt;&lt;encoding&gt;<br />
&nbsp;&nbsp;&nbsp; 即:&nbsp; &lt;语言&gt;&lt;比特位数&gt;&lt;编码&gt;<br />
&nbsp;&nbsp;&nbsp; 比如: ZHS16GBK表示采用GBK编码格式、16位（两个字节）简体中文字符集</p>
<p><strong>2.2字符编码方案<br />
</strong>2.2.1 单字节编码<br />
&nbsp;&nbsp;&nbsp; （1）单字节7位字符集，可以定义128个字符，最常用的字符集为US7ASCII<br />
&nbsp;&nbsp;&nbsp; （2）单字节8位字符集，可以定义256个字符，适合于欧洲大部分国家<br />
&nbsp;&nbsp;&nbsp; 例如：WE8ISO8859P1(西欧、8位、ISO标准8859P1编码)<br />
2.2.2 多字节编码<br />
&nbsp;&nbsp;&nbsp; （1）变长多字节编码<br />
&nbsp;&nbsp;&nbsp;&nbsp;某些字符用一个字节表示，其它字符用两个或多个字符表示，变长多字节编码常用于对亚洲语言的支持，&nbsp;&nbsp; 例如日语、汉语、印地语等<br />
&nbsp;&nbsp;&nbsp; 例如：AL32UTF8（其中AL代表ALL,指适用于所有语言）、zhs16cgb231280<br />
&nbsp;&nbsp;&nbsp; （2）定长多字节编码<br />
&nbsp;&nbsp;&nbsp; 每一个字符都使用固定长度字节的编码方案，目前oracle唯一支持的定长多字节编码是AF16UTF16，也是仅用于国家字符集<br />
2.2.3 unicode编码<br />
&nbsp;&nbsp;&nbsp; Unicode是一个涵盖了目前全世界使用的所有已知字符的单一编码方案，也就是说Unicode为每一个字符提供唯一的编码。UTF-16是unicode的16位编码方式，是一种定长多字节编码，用2个字节表示一个unicode字符，AF16UTF16是UTF-16编码字符集。<br />
&nbsp;&nbsp;&nbsp; UTF-8是unicode的8位编码方式，是一种变长多字节编码，这种编码可以用1、2、3个字节表示一个unicode字符，AL32UTF8，UTF8、UTFE是UTF-8编码字符集</p>
<p><strong>2.3 字符集超级<br />
</strong>&nbsp;&nbsp;&nbsp; 当一种字符集（字符集A）的编码数值包含所有另一种字符集（字符集B）的编码数值，并且两种字符集相同编码数值代表相同的字符时，则字符集A是字符集B的超级，或称字符集B是字符集A的子集。<br />
&nbsp;&nbsp;&nbsp; Oracle8i和oracle9i官方文档资料中备有子集-超级对照表（subset-superset pairs），例如：WE8ISO8859P1是WE8MSWIN1252的子集。由于US7ASCII是最早的Oracle数据库编码格式，因此有许多字符集是US7ASCII的超集，例如WE8ISO8859P1、ZHS16CGB231280、ZHS16GBK都是US7ASCII的超集。</p>
<p><strong>2.4 数据库字符集（oracle服务器端字符集）<br />
</strong>&nbsp;&nbsp;&nbsp; 数据库字符集在创建数据库时指定，在创建后通常不能更改。在创建数据库时，可以指定字符集(CHARACTER SET)和国家字符集(NATIONAL CHARACTER SET)。<br />
2.4.1字符集<br />
&nbsp;&nbsp;&nbsp; (1)用来存储CHAR, VARCHAR2, CLOB, LONG等类型数据<br />
&nbsp;&nbsp;&nbsp; (2)用来标示诸如表名、列名以及PL/SQL变量等<br />
&nbsp;&nbsp;&nbsp; (3)用来存储SQL和PL/SQL程序单元等<br />
2.4.2国家字符集：<br />
&nbsp;&nbsp;&nbsp; (1)用以存储NCHAR, NVARCHAR2, NCLOB等类型数据<br />
&nbsp;&nbsp;&nbsp; (2)国家字符集实质上是为oracle选择的附加字符集，主要作用是为了增强oracle的字符处理能力，因为NCHAR数据类型可以提供对亚洲使用定长多字节编码的支持，而数据库字符集则不能。国家字符集在oracle9i中进行了重新定义，只能在unicode编码中的AF16UTF16和UTF8中选择，默认值是AF16UTF16<br />
2.4.3查询字符集参数<br />
&nbsp;&nbsp;&nbsp; 可以查询以下数据字典或视图查看字符集设置情况<br />
&nbsp;&nbsp;&nbsp; nls_database_parameters、props$、v$nls_parameters<br />
&nbsp;&nbsp;&nbsp; 查询结果中NLS_CHARACTERSET表示字符集，NLS_NCHAR_CHARACTERSET表示国家字符集<br />
2.4.4修改数据库字符集<br />
&nbsp;&nbsp;&nbsp; 按照上文所说，数据库字符集在创建后原则上不能更改。如果需要修改字符集，通常需要导出数据库数据，重建数据库，再导入数据库数据的方式来转换，或通过ALTER DATABASE CHARACTER SET语句修改字符集，但创建数据库后修改字符集是有限制的，只有新的字符集是当前字符集的超集时才能修改数据库字符集，例如UTF8是US7ASCII的超集，修改数据库字符集可使用ALTER DATABASE CHARACTER SET UTF8。</p>
<p><strong>2.5 客户端字符集（NLS_LANG参数）</strong><br />
2.5.1客户端字符集含义<br />
&nbsp;&nbsp;&nbsp; 客户端字符集定义了客户端字符数据的编码方式，任何发自或发往客户端的字符数据均使用客户端定义的字符集编码,客户端可以看作是能与数据库直接连接的各种应用，例如sqlplus,exp/imp等。客户端字符集是通过设置NLS_LANG参数来设定的。<br />
2.5.2 NLS_LANG参数格式<br />
&nbsp;&nbsp;&nbsp; NLS_LANG=&lt;language&gt;_&lt;territory&gt;.&lt;client character set&gt; <br />
&nbsp;&nbsp;&nbsp; Language:显示oracle消息,校验，日期命名<br />
&nbsp;&nbsp;&nbsp; Territory：指定默认日期、数字、货币等格式<br />
&nbsp;&nbsp;&nbsp; Client character set：指定客户端将使用的字符集<br />
&nbsp;&nbsp;&nbsp; 例如：NLS_LANG=AMERICAN_AMERICA.US7ASCII&nbsp; <br />
&nbsp;&nbsp;&nbsp; AMERICAN是语言，AMERICA是地区，US7ASCII是客户端字符集<br />
2.5.3客户端字符集设置方法<br />
&nbsp;&nbsp;&nbsp;&nbsp; 1)UNIX环境<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $NLS_LANG=&#8220;simplified chinese&#8221;_china.zhs16gbk<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $export NLS_LANG<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 编辑oracle用户的profile文件<br />
&nbsp;&nbsp;&nbsp; 2)Windows环境<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 编辑注册表<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Regedit.exe---HKEY_LOCAL_MACHINE---SOFTWARE---ORACLE—HOME0<br />
2.5.4 NLS参数查询<br />
&nbsp;&nbsp;&nbsp; Oracle提供若干NLS参数定制数据库和用户机以适应本地格式，例如有NLS_LANGUAGE,NLS_DATE_FORMAT,NLS_CALENDER等，可以通过查询以下数据字典或v$视图查看。<br />
&nbsp;&nbsp;&nbsp; NLS_DATABASE_PARAMETERS--显示数据库当前NLS参数取值，包括数据库字符集取值<br />
&nbsp;&nbsp;&nbsp; NLS_SESSION_PARAMETERS--显示由NLS_LANG 设置的参数，或经过alter session 改变后的参数值（不包括由NLS_LANG 设置的客户端字符集）<br />
&nbsp;&nbsp;&nbsp; NLS_INSTANCE_PARAMETE--显示由参数文件init&lt;SID&gt;.ora 定义的参数V$NLS_PARAMETERS--显示数据库当前NLS参数取值<br />
2.5.5修改NLS参数<br />
&nbsp;&nbsp;&nbsp; 使用下列方法可以修改NLS参数<br />
&nbsp;&nbsp;&nbsp; （1）修改实例启动时使用的初始化参数文件<br />
&nbsp;&nbsp;&nbsp; （2）修改环境变量NLS_LANG<br />
&nbsp;&nbsp;&nbsp; （3）使用ALTER SESSION语句，在oracle会话中修改<br />
&nbsp;&nbsp;&nbsp; （4）使用某些SQL函数<br />
&nbsp;&nbsp;&nbsp; NLS作用优先级别：Sql function&gt;alter session&gt;环境变量或注册表&gt;参数文件&gt;数据库默认参数</p>
<p><strong>三．导入/导出与字符集转换</strong></p>
<p><strong>3.1 EXP/IMP<br />
</strong>&nbsp;&nbsp;&nbsp; Export 和 Import 是一对读写Oracle数据的工具。Export 将 Oracle 数据库中的数据输出到操作系统文件中, Import 把这些文件中的数据读到Oracle 数据库中，由于使用exp/imp进行数据迁移时，数据从源数据库到目标数据库的过程中有四个环节涉及到字符集，如果这四个环节的字符集不一致，将会发生字符集转换。</p>
<p>EXP&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </p>
<p align="center"><img src="http://www.csdb.cn/upload/112.bmp" border="0"  alt="" /></p>
<p>IMP&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </p>
<p align="center"><img src="http://www.csdb.cn/upload/113.bmp" border="0"  alt="" /></p>
<p>&nbsp;&nbsp;&nbsp; 四个字符集是<br />
&nbsp;&nbsp; （1）源数据库字符集 <br />
&nbsp;&nbsp; （2）Export过程中用户会话字符集（通过NLS_LANG设定）<br />
&nbsp;&nbsp; （3）Import过程中用户会话字符集（通过NLS_LANG设定）<br />
&nbsp;&nbsp; （4）目标数据库字符集</p>
<p><strong>3.2导出的转换过程<br />
</strong>&nbsp;&nbsp;&nbsp; 在Export过程中，如果源数据库字符集与Export用户会话字符集不一致，会发生字符集转换，并在导出文件的头部几个字节中存储Export用户会话字符集的ID号。在这个转换过程中可能发生数据的丢失。<br />
例:如果源数据库使用ZHS16GBK，而Export用户会话字符集使用US7ASCII，由于ZHS16GBK是16位字符集,而US7ASCII是7位字符集，这个转换过程中，中文字符在US7ASCII中不能够找到对等的字符，所以所有中文字符都会丢失而变成&#8220;?? &#8221;形式，这样转换后生成的Dmp文件已经发生了数据丢失。<br />
因此如果想正确导出源数据库数据，则Export过程中用户会话字符集应等于源数据库字符集或是源数据库字符集的超集</p>
<p><strong>3.3导入的转换过程</strong><br />
&nbsp;&nbsp;&nbsp; （1）确定导出数据库字符集环境<br />
&nbsp;&nbsp;&nbsp; 通过读取导出文件头，可以获得导出文件的字符集设置<br />
&nbsp;&nbsp;&nbsp; （2）确定导入session的字符集，即导入Session使用的NLS_LANG环境变量<br />
&nbsp;&nbsp;&nbsp; （3）IMP读取导出文件<br />
&nbsp;&nbsp;&nbsp; 读取导出文件字符集ID，和导入进程的NLS_LANG进行比较<br />
&nbsp;&nbsp;&nbsp; （4）如果导出文件字符集和导入Session字符集相同，那么在这一步骤内就不需要转换，如果不同，就需要把数据转换为导入Session使用的字符集。可以看出，导入数据到数据库过程中发生两次字符集转换<br />
&nbsp;&nbsp;&nbsp; 第一次:导入文件字符集与导入Session使用的字符集之间的转换，如果这个转换过程不能正确完成，Import向目标数据库的导入过程也就不能完成。<br />
&nbsp;&nbsp;&nbsp; 第二次:导入Session字符集与数据库字符集之间的转换。<br />
&nbsp;&nbsp;&nbsp; 然而,oracle8i的这种转换只能在单字节字符集之间进行,oracle8i导入Session不支持多字节字符集之间的转换，因此为了避免第一次转换，导入Session使用的NLS_LANG与导出文件字符集相同，第二次转换（通过SQL*Net）支持任何两种字符集。以上情况在Oracle9i中略有不同</p>
<p><strong>四．乱码问题</strong></p>
<p>&nbsp;&nbsp;&nbsp; oracle在数据存储、迁移过程中经常发生字符乱码问题，归根到底是由于字符集使用不当引起。下面以使用客户端sqlplus向数据库插入数据和导入/导出（EXP/IMP）过程为例，说明乱码产生的原因。</p>
<p><strong>4.1使用客户端sqlplus向数据库存储数据</strong><br />
&nbsp;&nbsp;&nbsp; 这个过程存在3个字符集设置<br />
&nbsp;&nbsp;&nbsp; （1）客户端应用字符集<br />
&nbsp;&nbsp;&nbsp; （2）客户端NLS_LANG参数设置<br />
&nbsp;&nbsp;&nbsp; （3）服务器端数据库字符集(Character Set)设置<br />
&nbsp;&nbsp;&nbsp; 客户端应用sqlplus中能够显示什么样的字符取决于客户端操作系统语言环境(客户端应用字符集)，但在应用中录入这些字符后，这些字符能否在数据库中正常存储，还与另外两个字符集设置紧密相关，其中客户端NLS_LANG参数主要用于字符数据传输过程中的转换判断。常见的乱码大致有两种情形：<br />
&nbsp;&nbsp;&nbsp; （1）汉字变成问号&#8220;？&#8221;；<br />
当从字符集A 转换成字符集B时，如果转换字符之间不存在对应关系，NLS_LANG使用替代字符&#8220;？&#8221;替代无法映射的字符<br />
&nbsp;&nbsp;&nbsp; （2）汉字变成未知字符（虽然有些是汉字，但与原字符含义不同）<br />
转换存在对应关系，但字符集A 中的字符编码与字符集B 中的字符编码代表不同含义</p>
<p><strong>4.2发生乱码原因</strong>&nbsp;<br />
&nbsp;&nbsp; &nbsp;乱码产生是由于几个字符集之间转换不匹配造成，分以下几种情况：<br />
&nbsp;&nbsp;&nbsp; （注：字符集之间如果不存在子集、超集对应关系时的情况不予考虑，因为这种情况下字符集之间转换必产生乱码）&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp; 1）服务器端数据库字符集与客户端应用字符集相同，与客户端NLS_LANG参数设置不同<br />
&nbsp;&nbsp;&nbsp; 如果客户端NLS_LANG字符集是其它两种字符集的子集，转换过程将出现乱码。<br />
&nbsp;&nbsp;&nbsp; 解决方法：将三种字符集设置成同一字符集，或NLS_LANG字符集是其它两种字符集的超集<br />
&nbsp;&nbsp;&nbsp; 2）服务器端数据库字符集与客户端NLS_LANG参数设置相同，与客户端应用字符集不同<br />
&nbsp;&nbsp;&nbsp; 如果客户端应用字符集是其它两种字符集的超集时，转换过程将出现乱码，但对于单字节编码存储中文问题，可参看本文第5章节的分析<br />
&nbsp;&nbsp;&nbsp; 3）客户端应用字符集、客户端NLS_LANG参数设置、服务器端数据库字符集互不相同<br />
&nbsp;&nbsp; &nbsp;此种情况较为复杂，但三种字符集之间只要有不能转换的字符，则必产生乱码</p>
<p><strong>4.3导入/导出过程出现乱码原因</strong><br />
&nbsp;&nbsp;&nbsp; 这个过程存在4个字符集设置，在3.1章节中已分析<br />
&nbsp;&nbsp; （1）源数据库字符集<br />
&nbsp;&nbsp; （2）EXP过程中NLS_LANG参数 <br />
&nbsp;&nbsp; （3）IMP过程中NLS_LANG参数<br />
&nbsp;&nbsp; （4）目标数据库字符集<br />
&nbsp;&nbsp;&nbsp; 出现乱码原因<br />
&nbsp;&nbsp;&nbsp; 1）当源数据库字符集不等于EXP过程中NLS_LANG参数，且源数据库字符集是EXP过程中NLS_LANG的子集，才能保证导出文件正确，其他情况则导出文件字符乱码<br />
&nbsp;&nbsp;&nbsp; 2）EXP过程中NLS_LANG字符集不等于IMP过程中NLS_LANG字符集，且EXP过程中NLS_LANG字符集是IMP过程中NLS_LANG字符集的子级, 才能保证第一次转换正常，否则第一次转换中出现乱码。<br />
&nbsp;&nbsp;&nbsp; 3）如果第一次转换正常，IMP过程中NLS_LANG字符集是目标数据库字符集的子集或相同，才能保证第二次转换正常，否则则第二次转换中出现乱码</p>
<p><strong>五．单字节编码存储中文问题</strong></p>
<p><strong>&nbsp;&nbsp;&nbsp; </strong>由于历史的原因，早期的oracle没有中文字符集（如oracle6、oracle7、oracle7.1）,但有的用户从那时起就使用数据库了，并用US7ASCII字符集存储了中文，或是有的用户在创建数据库时，不考虑清楚，随意选择一个默认的字符集，如WE8ISO8859P1或US7ASCII，而这两个字符集都没有汉字编码，虽然有些时候选用这种字符集好象也能正常使用，但用这种字符集存储汉字信息从原则上说就是错误的，它会给数据库的使用与维护带来一系列的麻烦。<br />
&nbsp;&nbsp;&nbsp; 正常情况下，要将汉字存入数据库，数据库字符集必须支持中文，而将数据库字符集设置为US7ASCII等单字节字符集是不合适的。US7ASCII字符集只定义了128个符号，并不支持汉字。另外，如果在SQL*PLUS中能够输入中文，操作系统缺省应该是支持中文的，但如果在NLS_LANG中的字符集设置为US7ASCII，显然也是不正确的，它没有反映客户端的实际情况。但在实际应用中汉字显示却是正确的，这主要是因为Oracle检查数据库与客户端的字符集设置是同样的，那么数据在客户与数据库之间的存取过程中将不发生任何转换，但是这实际上导致了数据库标识的字符集与实际存入的内容是不相符的。而在SELECT的过程中，Oracle同样检查发现数据库与客户端的字符集设置是相同的，所以它也将存入的内容原封不动地传送到客户端，而客户端操作系统识别出这是汉字编码所以能够正确显示。<br />
&nbsp;&nbsp;&nbsp; 在这个例子中，数据库与客户端都没有设置成中文字符集，但却能正常显示中文，从应用的角度看好象没问题。然而这里面却存在着极大的隐患，比如在应用length或substr等字符串函数时，就可能得到意外的结果。<br />
&nbsp;&nbsp;&nbsp; 对于早期使用US7ASCII字符集数据库的数据迁移到oracle8i/9i中（使用zhs16gbk），由于原始数据已经按照US7ASCII格式存储，对于这种情况，可以通过使用Oracle8i的导出工具，设置导出字符集为US7ASCII，导出后使用UltraEdit等工具打开dmp文件，修改第二、三字符，修改 0001 为0354,这样就可以将US7ASCII字符集的数据正确导入到ZHS16GBK的数据库中。</p>
<p><strong>六．结束语</strong></p>
<p>&nbsp;&nbsp;&nbsp; 为了避免在数据库迁移过程中由于字符集不同导致的数据损失，oracle提供了字符集扫描工具（character set scanner），通过这个工具我们可以测试在数据迁移过程中由于字符集转换可能带来的问题，然后根据测试结果，确定数据迁移过程中最佳字符集解决方案。</p>
</div>
<img src ="http://www.blogjava.net/i369/aggbug/148004.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/i369/" target="_blank">芦苇</a> 2007-09-25 10:53 <a href="http://www.blogjava.net/i369/articles/148004.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Oracle 字符集问题 </title><link>http://www.blogjava.net/i369/articles/147165.html</link><dc:creator>芦苇</dc:creator><author>芦苇</author><pubDate>Fri, 21 Sep 2007 09:30:00 GMT</pubDate><guid>http://www.blogjava.net/i369/articles/147165.html</guid><wfw:comment>http://www.blogjava.net/i369/comments/147165.html</wfw:comment><comments>http://www.blogjava.net/i369/articles/147165.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/i369/comments/commentRss/147165.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/i369/services/trackbacks/147165.html</trackback:ping><description><![CDATA[<br />
<script>function StorePage(){d=document;t=d.selection?(d.selection.type!='None'?d.selection.createRange().text:''):(d.getSelection?d.getSelection():'');void(keyit=window.open('http://www.365key.com/storeit.aspx?t='+escape(d.title)+'&u='+escape(d.location.href)+'&c='+escape(t),'keyit','scrollbars=no,width=475,height=575,left=75,top=20,status=no,resizable=yes'));keyit.focus();}</script>
<div class="post">
<div class="postTitle"><script src="http://wz.csdn.net/javascripts/vote.js"></script><iframe style="margin-top: 0px; float: left" border="0" marginwidth="0" framespacing="0" marginheight="0" src="http://wz.csdn.net/vote.aspx?t=Oracle%20%u5BA2%u6237%u7AEF%20NLS_LANG%20%u7684%u8BBE%u7F6E%20-%20wzy0623%u7684%u4E13%u680F%20-%20CSDNBlog&amp;u=http%3A//blog.csdn.net/wzy0623/archive/2007/07/09/1683337.aspx" frameborder="0" noResize width="54" scrolling="no" height="75"></iframe><a href="http://blog.csdn.net/wzy0623/archive/2007/07/09/1683337.aspx"><img height="13" src="http://blog.csdn.net/images/authorship.gif" width="15" border="0"  alt="" />&nbsp;Oracle 客户端 NLS_LANG 的设置</a>&nbsp;&nbsp; <script src="http://blog.csdn.net/count.aspx?ID=1683337&amp;Type=Rank"></script><span title="文章指数:70"><img src="http://blog.csdn.net/images/star.gif" border="0"  alt="" /><img src="http://blog.csdn.net/images/star.gif" border="0"  alt="" /><img src="http://blog.csdn.net/images/star.gif" border="0"  alt="" /><img src="http://blog.csdn.net/images/star_half.gif" border="0"  alt="" /></span>&nbsp;&nbsp;<img title="CSDN Blog推出文章指数概念，文章指数是对Blog文章综合评分后推算出的，综合评分项分别是该文章的点击量，回复次数，被网摘收录数量，文章长度和文章类型；满分100，每月更新一次。" alt="CSDN Blog推出文章指数概念，文章指数是对Blog文章综合评分后推算出的，综合评分项分别是该文章的点击量，回复次数，被网摘收录数量，文章长度和文章类型；满分100，每月更新一次。" src="http://blog.csdn.net/images/ask.gif" border="0" /> </div>
<div class="postText">
<p><strong>1. NLS_LANG 参数组成</strong><br />
NLS_LANG参数由以下部分组成:<br />
NLS_LANG=&lt;Language&gt;_&lt;Territory&gt;.&lt;Clients Characterset&gt;</p>
<p>NLS_LANG各部分含义如下:<br />
LANGUAGE指定:<br />
-Oracle消息使用的语言<br />
-日期中月份和日显示<br />
TERRITORY指定<br />
-货币和数字格式<br />
-地区和计算星期及日期的习惯<br />
CHARACTERSET:<br />
-控制客户端应用程序使用的字符集<br />
通常设置或者等于客户端(如Windows)代码页 <br />
或者对于unicode应用设置为UTF8</p>
<p>在Windows上查看当前系统的代码页可以使用chcp命令:<br />
E:\&gt;chcp<br />
&nbsp;活动的代码页: 936</p>
<p>代码页936也就是中文字符集 GBK,在Microsoft的官方站点上，我们可以遭到关于936代码页的具体编码规则,请参考以下链接:<br />
<a href="http://www.microsoft.com/globaldev/reference/dbcs/936.htm">http://www.microsoft.com/globaldev/reference/dbcs/936.htm</a></p>
<p><br />
<strong>2. 查看 NLS_LANG 的方法</strong><br />
Windows使用:</p>
<p>echo %NLS_LANG%<br />
如:<br />
E:\&gt;echo %NLS_LANG%<br />
AMERICAN_AMERICA.ZHS16GBK</p>
<p>Unix使用:</p>
<p>env|grep NLS_LANG<br />
如:<br />
/opt/oracle&gt;env|grep NLS_LANG<br />
NLS_LANG=AMERICAN_CHINA.ZHS16GBK</p>
<p>Windows客户端设置,可以在注册表中更改NLS_LANG,具体键值位于:<br />
HKEY_LOCAL_MACHINE\SOFTWARE\ORACLE\HOMExx\<br />
xx指存在多个ORACLE_HOME时系统编号。</p>
<p><br />
<strong>3. 查看数据库当前字符集参数设置</strong><br />
SELECT * FROM v$nls_parameters;</p>
<p><br />
<strong>4. 查看数据库可用字符集参数设置</strong><br />
SELECT * FROM v$nls_valid_values;</p>
<p><br />
<strong>5. 客户端 NLS_LANG 的设置方法</strong><br />
Windows:<br />
# 常用中文字符集<br />
set NLS_LANG=SIMPLIFIED CHINESE_CHINA.ZHS16GBK<br />
# 常用unicode字符集<br />
set NLS_LANG=american_america.AL32UTF8<br />
可以通过修改注册表键值永久设置<br />
HKEY_LOCAL_MACHINE\SOFTWARE\ORACLE\HOMExx\NLS_LANG</p>
<p>Unix:<br />
# 常用unicode字符集<br />
export NLS_LANG=american_america.AL32UTF8<br />
# 常用中文字符集<br />
export NLS_LANG="Simplified Chinese_china".ZHS16GBK<br />
可以编辑 bash_profile 文件进行永久设置<br />
vi .bash_profile<br />
NLS_LANG="Simplified Chinese_china".ZHS16GBK export NLS_LANG<br />
# 使 bash_profile 设置生效<br />
source .bash_profile</p>
<p><br />
参考：<br />
<a href="http://www.eygle.com/special/NLS_CHARACTER_SET_04.htm">http://www.eygle.com/special/NLS_CHARACTER_SET_04.htm</a>&nbsp;</p>
</div>
</div>
<br />
<br />
<p><strong><font face="宋体" size="3">一．引言</font> </strong></p>
<p><font size="3"><font face="宋体"><strong><span>&nbsp;&nbsp;&nbsp; </span></strong><span>ORACLE</span>数据库字符集，即<span>Oracle</span>全球化支持<span>(Globalization Support)</span>，或即国家语言支持（<span>NLS</span>）其作用是用本国语言和格式来存储、处理和检索数据。利用全球化支持，<span>ORACLE</span>为用户提供自己熟悉的数据库母语环境，诸如日期格式、数字格式和存储序列等。<span>Oracle</span>可以支持多种语言及字符集，其中<span>oracle8i</span>支持<span>48</span>种语言、<span>76</span>个国家地域、<span>229</span>种字符集，而<span>oracle9i</span>则支持<span>57</span>种语言、<span>88</span>个国家地域、<span>235</span>种字符集。由于<span>oracle</span>字符集种类多，且在存储、检索、迁移<span>oracle</span>数据时多个环节与字符集的设置密切相关，因此在实际的应用中，数据库开发和管理人员经常会遇到有关<span>oracle</span>字符集方面的问题。本文通过以下几个方面阐述，对<span>oracle</span>字符集做简要分析</font> </font></p>
<p><strong><font face="宋体" size="3">二．字符集基本知识</font> </strong></p>
<p><strong><font size="3"><font face="宋体"><span>2.1</span>字符集</font> </font></strong><strong><span><br />
</span></strong><font size="3"><font face="宋体"><span>&nbsp;&nbsp;&nbsp; </span>实质就是按照一定的字符编码方案，对一组特定的符号，分别赋予不同数值编码的集合。<span>Oracle</span>数据库最早支持的编码方案是<span>US7ASCII</span>。</font> </font><span><br />
<font face="宋体" size="3">&nbsp;&nbsp;&nbsp; Oracle</font> </span><font face="宋体" size="3">的字符集命名遵循以下命名规则</font> <font size="3"><font face="宋体"><span>:<br />
&nbsp;&nbsp;&nbsp; <language></language><bit size=";"></bit><encoding></encoding><br />
&nbsp;&nbsp;&nbsp; &lt;</span>语言<span>&gt;&lt;</span>比特位数<span>&gt;&lt;</span>编码</font> </font><font size="3"><font face="宋体"><span>&gt;<br />
&nbsp;&nbsp;&nbsp; </span>比如<span>: ZHS16GBK</span>表示采用<span>GBK</span>编码格式、<span>16</span>位（两个字节）简体中文字符集</font> </font></p>
<p><strong><font size="3"><font face="宋体"><span>2.2</span>字符编码方案</font> </font></strong><strong><span><br />
</span></strong><font size="3"><font face="宋体"><span>2.2.1</span> 单字节编码</font> </font><span><br />
<font face="宋体" size="3">&nbsp;&nbsp;&nbsp; </font></span><font face="宋体" size="3">（<span>1</span>）单字节<span>7</span>位字符集，可以定义<span>128</span>个字符，最常用的字符集为</font> <font size="3"><font face="宋体"><span>US7ASCII<br />
&nbsp;&nbsp;&nbsp; </span>（<span>2</span>）单字节<span>8</span>位字符集，可以定义<span>256</span>个字符，适合于欧洲大部分国家</font> </font><span><br />
<font face="宋体" size="3">&nbsp;&nbsp;&nbsp; </font></span><font face="宋体" size="3">例如：<span>WE8ISO8859P1(</span>西欧、<span>8</span>位、<span>ISO</span>标准<span>8859P1</span>编码</font> <font size="3"><font face="宋体"><span>)<br />
2.2.2 </span>多字节编码</font> </font><span><br />
<font face="宋体" size="3">&nbsp;&nbsp;&nbsp; </font></span><font face="宋体" size="3">（<span>1</span>）变长多字节编码</font> <span><br />
<font face="宋体" size="3">&nbsp;&nbsp;&nbsp;&nbsp;</font> </span><font face="宋体" size="3">某些字符用一个字节表示，其它字符用两个或多个字符表示，变长多字节编码常用于对亚洲语言的支持，<span>&nbsp;&nbsp; </span>例如日语、汉语、印地语等</font> <span><br />
<font face="宋体" size="3">&nbsp;&nbsp;&nbsp; </font></span><font face="宋体" size="3">例如：<span>AL32UTF8</span>（其中<span>AL</span>代表<span>ALL,</span>指适用于所有语言）、</font> <font size="3"><font face="宋体"><span>zhs16cgb231280<br />
&nbsp;&nbsp;&nbsp; </span>（<span>2</span>）定长多字节编码</font> </font><span><br />
<font face="宋体" size="3">&nbsp;&nbsp;&nbsp; </font></span><font face="宋体" size="3">每一个字符都使用固定长度字节的编码方案，目前<span>oracle</span>唯一支持的定长多字节编码是<span>AF16UTF16</span>，也是仅用于国家字符集</font> <span><br />
<font face="宋体" size="3">2.2.3 unicode</font> </span><font face="宋体" size="3">编码</font> <span><br />
<font face="宋体" size="3">&nbsp;&nbsp;&nbsp; Unicode</font> </span><font face="宋体" size="3">是一个涵盖了目前全世界使用的所有已知字符的单一编码方案，也就是说<span>Unicode</span>为每一个字符提供唯一的编码。<span>UTF-16</span>是<span>unicode</span>的<span>16</span>位编码方式，是一种定长多字节编码，用<span>2</span>个字节表示一个<span>unicode</span>字符，<span>AF16UTF16</span>是<span>UTF-16</span>编码字符集。</font> <span><br />
<font face="宋体" size="3">&nbsp;&nbsp;&nbsp; UTF-8</font> </span><font face="宋体" size="3">是<span>unicode</span>的<span>8</span>位编码方式，是一种变长多字节编码，这种编码可以用<span>1</span>、<span>2</span>、<span>3</span>个字节表示一个<span>unicode</span>字符，<span>AL32UTF8</span>，<span>UTF8</span>、<span>UTFE</span>是<span>UTF-8</span>编码字符集</font> </p>
<p><strong><font size="3"><font face="宋体"><span>2.3 </span>字符集超级</font> </font></strong><strong><span><br />
</span></strong><font size="3"><font face="宋体"><span>&nbsp;&nbsp;&nbsp; </span>当一种字符集（字符集<span>A</span>）的编码数值包含所有另一种字符集（字符集<span>B</span>）的编码数值，并且两种字符集相同编码数值代表相同的字符时，则字符集<span>A</span>是字符集<span>B</span>的超级，或称字符集<span>B</span>是字符集<span>A</span>的子集。</font> </font><span><br />
<font face="宋体" size="3">&nbsp;&nbsp;&nbsp; Oracle8i</font> </span><font face="宋体" size="3">和<span>oracle9i</span>官方文档资料中备有子集<span>-</span>超级对照表（<span>subset-superset pairs</span>），例如：<span>WE8ISO8859P1</span>是<span>WE8MSWIN1252</span>的子集。由于<span>US7ASCII</span>是最早的<span>Oracle</span>数据库编码格式，因此有许多字符集是<span>US7ASCII</span>的超集，例如<span>WE8ISO8859P1</span>、<span>ZHS16CGB231280</span>、<span>ZHS16GBK</span>都是<span>US7ASCII</span>的超集。</font> </p>
<p><strong><font size="3"><font face="宋体"><span>2.4 </span>数据库字符集（<span>oracle</span>服务器端字符集）</font> </font></strong><strong><span><br />
</span></strong><font size="3"><font face="宋体"><span>&nbsp;&nbsp;&nbsp; </span>数据库字符集在创建数据库时指定，在创建后通常不能更改。在创建数据库时，可以指定字符集<span>(CHARACTER SET)</span>和国家字符集<span>(NATIONAL CHARACTER SET)</span>。</font> </font><span><br />
<font face="宋体" size="3">2.4.1</font> </span><font face="宋体" size="3">字符集</font> <span><br />
<font face="宋体" size="3">&nbsp;&nbsp;&nbsp; (1)</font> </span><font face="宋体" size="3">用来存储<span>CHAR, VARCHAR2, CLOB, LONG</span>等类型数据</font> <span><br />
<font face="宋体" size="3">&nbsp;&nbsp;&nbsp; (2)</font> </span><font face="宋体" size="3">用来标示诸如表名、列名以及<span>PL/SQL</span>变量等</font> <span><br />
<font face="宋体" size="3">&nbsp;&nbsp;&nbsp; (3)</font> </span><font face="宋体" size="3">用来存储<span>SQL</span>和<span>PL/SQL</span>程序单元等</font> <span><br />
<font face="宋体" size="3">2.4.2</font> </span><font face="宋体" size="3">国家字符集：</font> <span><br />
<font face="宋体" size="3">&nbsp;&nbsp;&nbsp; (1)</font> </span><font face="宋体" size="3">用以存储<span>NCHAR, NVARCHAR2, NCLOB</span>等类型数据</font> <span><br />
<font face="宋体" size="3">&nbsp;&nbsp;&nbsp; (2)</font> </span><font face="宋体" size="3">国家字符集实质上是为<span>oracle</span>选择的附加字符集，主要作用是为了增强<span>oracle</span>的字符处理能力，因为<span>NCHAR</span>数据类型可以提供对亚洲使用定长多字节编码的支持，而数据库字符集则不能。国家字符集在<span>oracle9i</span>中进行了重新定义，只能在<span>unicode</span>编码中的<span>AF16UTF16</span>和<span>UTF8</span>中选择，默认值是</font> <font size="3"><font face="宋体"><span>AF16UTF16<br />
2.4.3</span>查询字符集参数</font> </font><span><br />
<font face="宋体" size="3">&nbsp;&nbsp;&nbsp; </font></span><font face="宋体" size="3">可以查询以下数据字典或视图查看字符集设置情况</font> <span><br />
<font face="宋体" size="3">&nbsp;&nbsp;&nbsp; nls_database_parameters</font> </span><font face="宋体" size="3">、<span>props$</span>、</font> <font size="3"><font face="宋体"><span>v$nls_parameters<br />
&nbsp;&nbsp;&nbsp; </span>查询结果中<span>NLS_CHARACTERSET</span>表示字符集，<span>NLS_NCHAR_CHARACTERSET</span>表示国家字符集</font> </font><span><br />
<font face="宋体" size="3">2.4.4</font> </span><font face="宋体" size="3">修改数据库字符集</font> <span><br />
<font face="宋体" size="3">&nbsp;&nbsp;&nbsp; </font></span><font face="宋体" size="3">按照上文所说，数据库字符集在创建后原则上不能更改。如果需要修改字符集，通常需要导出数据库数据，重建数据库，再导入数据库数据的方式来转换，或通过<span>ALTER DATABASE CHARACTER SET</span>语句修改字符集，但创建数据库后修改字符集是有限制的，只有新的字符集是当前字符集的超集时才能修改数据库字符集，例如<span>UTF8</span>是<span>US7ASCII</span>的超集，修改数据库字符集可使用<span>ALTER DATABASE CHARACTER SET UTF8</span>。</font> </p>
<p><strong><font size="3"><font face="宋体"><span>2.5 </span>客户端字符集（<span>NLS_LANG</span>参数）</font> </font></strong><span><br />
<font face="宋体" size="3">2.5.1</font> </span><font face="宋体" size="3">客户端字符集含义</font> <span><br />
<font face="宋体" size="3">&nbsp;&nbsp;&nbsp; </font></span><font face="宋体" size="3">客户端字符集定义了客户端字符数据的编码方式，任何发自或发往客户端的字符数据均使用客户端定义的字符集编码<span>,</span>客户端可以看作是能与数据库直接连接的各种应用，例如<span>sqlplus,exp/imp</span>等。客户端字符集是通过设置<span>NLS_LANG</span>参数来设定的。</font> <span><br />
<font face="宋体" size="3">2.5.2 NLS_LANG</font> </span><font face="宋体" size="3">参数格式</font> <span><br />
<font face="宋体" size="3">&nbsp;&nbsp;&nbsp; NLS_LANG=<language></language>_<territory></territory>.<client set="" character=";"></client><br />
&nbsp;&nbsp;&nbsp; Language:</font> </span><font face="宋体" size="3">显示<span>oracle</span>消息<span>,</span>校验，日期命名</font> <span><br />
<font face="宋体" size="3">&nbsp;&nbsp;&nbsp; Territory</font> </span><font face="宋体" size="3">：指定默认日期、数字、货币等格式</font> <span><br />
<font face="宋体" size="3">&nbsp;&nbsp;&nbsp; Client character set</font> </span><font face="宋体" size="3">：指定客户端将使用的字符集</font> <span><br />
<font face="宋体" size="3">&nbsp;&nbsp;&nbsp; </font></span><font face="宋体" size="3">例如：</font> <font size="3"><font face="宋体"><span>NLS_LANG=AMERICAN_AMERICA.US7ASCII&nbsp; <br />
&nbsp;&nbsp;&nbsp; AMERICAN</span>是语言，<span>AMERICA</span>是地区，<span>US7ASCII</span>是客户端字符集</font> </font><span><br />
<font face="宋体" size="3">2.5.3</font> </span><font face="宋体" size="3">客户端字符集设置方法</font> <span><br />
<font face="宋体" size="3">&nbsp;&nbsp;&nbsp;&nbsp; 1)UNIX</font> </span><font face="宋体" size="3">环境</font> <span><br />
<font face="宋体" size="3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $NLS_LANG=&#8220;simplified chinese&#8221;_china.zhs16gbk<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $export NLS_LANG<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font></span><font face="宋体" size="3">编辑<span>oracle</span>用户的<span>profile</span>文件</font> <span><br />
<font face="宋体" size="3">&nbsp;&nbsp;&nbsp; 2)Windows</font> </span><font face="宋体" size="3">环境</font> <span><br />
<font face="宋体" size="3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font></span><font face="宋体" size="3">编辑注册表</font> <span><br />
<font face="宋体" size="3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Regedit.exe---HKEY_LOCAL_MACHINE---SOFTWARE---ORACLE—HOME0<br />
2.5.4 NLS</font> </span><font face="宋体" size="3">参数查询</font> <span><br />
<font face="宋体" size="3">&nbsp;&nbsp;&nbsp; Oracle</font> </span><font face="宋体" size="3">提供若干<span>NLS</span>参数定制数据库和用户机以适应本地格式，例如有<span>NLS_LANGUAGE,NLS_DATE_FORMAT,NLS_CALENDER</span>等，可以通过查询以下数据字典或<span>v$</span>视图查看。</font> <span><br />
<font face="宋体" size="3">&nbsp;&nbsp;&nbsp; NLS_DATABASE_PARAMETERS--</font> </span><font face="宋体" size="3">显示数据库当前<span>NLS</span>参数取值，包括数据库字符集取值</font> <span><br />
<font face="宋体" size="3">&nbsp;&nbsp;&nbsp; NLS_SESSION_PARAMETERS--</font> </span><font face="宋体" size="3">显示由<span>NLS_LANG </span>设置的参数，或经过<span>alter session </span>改变后的参数值（不包括由<span>NLS_LANG </span>设置的客户端字符集）</font> <span><br />
<font face="宋体" size="3">&nbsp;&nbsp;&nbsp; NLS_INSTANCE_PARAMETE--</font> </span><font face="宋体" size="3">显示由参数文件<span>init<sid></sid>.ora </span>定义的参数<span>V$NLS_PARAMETERS--</span>显示数据库当前<span>NLS</span>参数取值</font> <span><br />
<font face="宋体" size="3">2.5.5</font> </span><font face="宋体" size="3">修改<span>NLS</span>参数</font> <span><br />
<font face="宋体" size="3">&nbsp;&nbsp;&nbsp; </font></span><font face="宋体" size="3">使用下列方法可以修改<span>NLS</span>参数</font> <span><br />
<font face="宋体" size="3">&nbsp;&nbsp;&nbsp; </font></span><font face="宋体" size="3">（<span>1</span>）修改实例启动时使用的初始化参数文件</font> <span><br />
<font face="宋体" size="3">&nbsp;&nbsp;&nbsp; </font></span><font face="宋体" size="3">（<span>2</span>）修改环境变量</font> <font size="3"><font face="宋体"><span>NLS_LANG<br />
&nbsp;&nbsp;&nbsp; </span>（<span>3</span>）使用<span>ALTER SESSION</span>语句，在<span>oracle</span>会话中修改</font> </font><span><br />
<font face="宋体" size="3">&nbsp;&nbsp;&nbsp; </font></span><font face="宋体" size="3">（<span>4</span>）使用某些<span>SQL</span>函数</font> <span><br />
<font face="宋体" size="3">&nbsp;&nbsp;&nbsp; NLS</font> </span><font face="宋体" size="3">作用优先级别：<span>Sql function&gt;alter session&gt;</span>环境变量或注册表<span>&gt;</span>参数文件<span>&gt;</span>数据库默认参数</font> </p>
<p><strong><font face="宋体" size="3">三．导入<span>/</span>导出与字符集转换</font> </strong></p>
<p><strong><span><font face="宋体" size="3">3.1 EXP/IMP</font> </span></strong><strong><span><br />
</span></strong><font size="3"><font face="宋体"><span>&nbsp;&nbsp;&nbsp; Export </span>和<span> Import </span>是一对读写<span>Oracle</span>数据的工具。<span>Export </span>将<span> Oracle </span>数据库中的数据输出到操作系统文件中<span>, Import </span>把这些文件中的数据读到<span>Oracle </span>数据库中，由于使用<span>exp/imp</span>进行数据迁移时，数据从源数据库到目标数据库的过程中有四个环节涉及到字符集，如果这四个环节的字符集不一致，将会发生字符集转换。</font> </font></p>
<p><span><font face="宋体" size="3">EXP<br />
&nbsp;&nbsp;&nbsp;&nbsp; ____________&nbsp; &nbsp;_________________&nbsp; _____________<br />
&nbsp;&nbsp;&nbsp;&nbsp; |imp导入文件|&lt;-&gt;&lt;-&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;------------&nbsp;&nbsp; -----------------&nbsp;&nbsp;-------------</font> </span></p>
<p align="center"><span><font size="3"><font face="宋体"></font></font></span></p>
<p><span><font face="宋体" size="3">IMP&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp; ____________&nbsp; &nbsp;_________________&nbsp; _____________<br />
&nbsp;&nbsp;&nbsp;&nbsp; |imp导入文件|-&gt;|环境变量NLS_LANG|-&gt;|数据库字符集|<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;------------&nbsp;&nbsp; -----------------&nbsp;&nbsp;-------------</font> </span></p>
<p align="center"><span><font size="3"><font face="宋体"></font></font></span></p>
<p><font size="3"><font face="宋体"><span>&nbsp;&nbsp;&nbsp; </span>四个字符集是</font> </font><span><br />
<font face="宋体" size="3">&nbsp;&nbsp; </font></span><font face="宋体" size="3">（<span>1</span>）源数据库字符集 </font><span><br />
<font face="宋体" size="3">&nbsp;&nbsp; </font></span><font face="宋体" size="3">（<span>2</span>）<span>Export</span>过程中用户会话字符集（通过<span>NLS_LANG</span>设定）</font> <span><br />
<font face="宋体" size="3">&nbsp;&nbsp; </font></span><font face="宋体" size="3">（<span>3</span>）<span>Import</span>过程中用户会话字符集（通过<span>NLS_LANG</span>设定）</font> <span><br />
<font face="宋体" size="3">&nbsp;&nbsp; </font></span><font face="宋体" size="3">（<span>4</span>）目标数据库字符集</font> </p>
<p><strong><font size="3"><font face="宋体"><span>3.2</span>导出的转换过程</font> </font></strong><strong><span><br />
</span></strong><font size="3"><font face="宋体"><span>&nbsp;&nbsp;&nbsp; </span>在<span>Export</span>过程中，如果源数据库字符集与<span>Export</span>用户会话字符集不一致，会发生字符集转换，并在导出文件的头部几个字节中存储<span>Export</span>用户会话字符集的<span>ID</span>号。在这个转换过程中可能发生数据的丢失。</font> </font><span><br />
</span><font face="宋体" size="3">例<span>:</span>如果源数据库使用<span>ZHS16GBK</span>，而<span>Export</span>用户会话字符集使用<span>US7ASCII</span>，由于<span>ZHS16GBK</span>是<span>16</span>位字符集<span>,</span>而<span>US7ASCII</span>是<span>7</span>位字符集，这个转换过程中，中文字符在<span>US7ASCII</span>中不能够找到对等的字符，所以所有中文字符都会丢失而变成<span>&#8220;?? &#8221;</span>形式，这样转换后生成的<span>Dmp</span>文件已经发生了数据丢失。</font> <span><br />
</span><font face="宋体" size="3">因此如果想正确导出源数据库数据，则<span>Export</span>过程中用户会话字符集应等于源数据库字符集或是源数据库字符集的超集</font> </p>
<p><strong><font size="3"><font face="宋体"><span>3.3</span>导入的转换过程</font> </font></strong><span><br />
<font face="宋体" size="3">&nbsp;&nbsp;&nbsp; </font></span><font face="宋体" size="3">（<span>1</span>）确定导出数据库字符集环境</font> <span><br />
<font face="宋体" size="3">&nbsp;&nbsp;&nbsp; </font></span><font face="宋体" size="3">通过读取导出文件头，可以获得导出文件的字符集设置</font> <span><br />
<font face="宋体" size="3">&nbsp;&nbsp;&nbsp; </font></span><font face="宋体" size="3">（<span>2</span>）确定导入<span>session</span>的字符集，即导入<span>Session</span>使用的<span>NLS_LANG</span>环境变量</font> <span><br />
<font face="宋体" size="3">&nbsp;&nbsp;&nbsp; </font></span><font face="宋体" size="3">（<span>3</span>）<span>IMP</span>读取导出文件</font> <span><br />
<font face="宋体" size="3">&nbsp;&nbsp;&nbsp; </font></span><font face="宋体" size="3">读取导出文件字符集<span>ID</span>，和导入进程的<span>NLS_LANG</span>进行比较</font> <span><br />
<font face="宋体" size="3">&nbsp;&nbsp;&nbsp; </font></span><font face="宋体" size="3">（<span>4</span>）如果导出文件字符集和导入<span>Session</span>字符集相同，那么在这一步骤内就不需要转换，如果不同，就需要把数据转换为导入<span>Session</span>使用的字符集。可以看出，导入数据到数据库过程中发生两次字符集转换</font> <span><br />
<font face="宋体" size="3">&nbsp;&nbsp;&nbsp; </font></span><font face="宋体" size="3">第一次<span>:</span>导入文件字符集与导入<span>Session</span>使用的字符集之间的转换，如果这个转换过程不能正确完成，<span>Import</span>向目标数据库的导入过程也就不能完成。</font> <span><br />
<font face="宋体" size="3">&nbsp;&nbsp;&nbsp; </font></span><font face="宋体" size="3">第二次<span>:</span>导入<span>Session</span>字符集与数据库字符集之间的转换。</font> <span><br />
<font face="宋体" size="3">&nbsp;&nbsp;&nbsp; </font></span><font face="宋体" size="3">然而<span>,oracle8i</span>的这种转换只能在单字节字符集之间进行<span>,oracle8i</span>导入<span>Session</span>不支持多字节字符集之间的转换，因此为了避免第一次转换，导入<span>Session</span>使用的<span>NLS_LANG</span>与导出文件字符集相同，第二次转换（通过<span>SQL*Net</span>）支持任何两种字符集。以上情况在<span>Oracle9i</span>中略有不同</font> </p>
<p><strong><font face="宋体" size="3">四．乱码问题</font> </strong></p>
<p><font size="3"><font face="宋体"><span>&nbsp;&nbsp;&nbsp; oracle</span>在数据存储、迁移过程中经常发生字符乱码问题，归根到底是由于字符集使用不当引起。下面以使用客户端<span>sqlplus</span>向数据库插入数据和导入<span>/</span>导出（<span>EXP/IMP</span>）过程为例，说明乱码产生的原因。</font> </font></p>
<p><strong><font size="3"><font face="宋体"><span>4.1</span>使用客户端<span>sqlplus</span>向数据库存储数据</font> </font></strong><span><br />
<font face="宋体" size="3">&nbsp;&nbsp;&nbsp; </font></span><font face="宋体" size="3">这个过程存在<span>3</span>个字符集设置</font> <span><br />
<font face="宋体" size="3">&nbsp;&nbsp;&nbsp; </font></span><font face="宋体" size="3">（<span>1</span>）客户端应用字符集</font> <span><br />
<font face="宋体" size="3">&nbsp;&nbsp;&nbsp; </font></span><font face="宋体" size="3">（<span>2</span>）客户端<span>NLS_LANG</span>参数设置</font> <span><br />
<font face="宋体" size="3">&nbsp;&nbsp;&nbsp; </font></span><font face="宋体" size="3">（<span>3</span>）服务器端数据库字符集<span>(Character Set)</span>设置</font> <span><br />
<font face="宋体" size="3">&nbsp;&nbsp;&nbsp; </font></span><font face="宋体" size="3">客户端应用<span>sqlplus</span>中能够显示什么样的字符取决于客户端操作系统语言环境<span>(</span>客户端应用字符集<span>)</span>，但在应用中录入这些字符后，这些字符能否在数据库中正常存储，还与另外两个字符集设置紧密相关，其中客户端<span>NLS_LANG</span>参数主要用于字符数据传输过程中的转换判断。常见的乱码大致有两种情形：</font> <span><br />
<font face="宋体" size="3">&nbsp;&nbsp;&nbsp; </font></span><font face="宋体" size="3">（<span>1</span>）汉字变成问号<span>&#8220;</span>？<span>&#8221;</span>；</font> <span><br />
</span><font face="宋体" size="3">当从字符集<span>A </span>转换成字符集<span>B</span>时，如果转换字符之间不存在对应关系，<span>NLS_LANG</span>使用替代字符<span>&#8220;</span>？<span>&#8221;</span>替代无法映射的字符</font> <span><br />
<font face="宋体" size="3">&nbsp;&nbsp;&nbsp; </font></span><font face="宋体" size="3">（<span>2</span>）汉字变成未知字符（虽然有些是汉字，但与原字符含义不同）</font> <span><br />
</span><font face="宋体" size="3">转换存在对应关系，但字符集<span>A </span>中的字符编码与字符集<span>B </span>中的字符编码代表不同含义</font> </p>
<p><strong><font size="3"><font face="宋体"><span>4.2</span>发生乱码原因</font> </font></strong><font size="3"><font face="宋体"><span>&nbsp;<br />
&nbsp;&nbsp; &nbsp;</span>乱码产生是由于几个字符集之间转换不匹配造成，分以下几种情况：</font> </font><span><br />
<font face="宋体" size="3">&nbsp;&nbsp;&nbsp; </font></span><font face="宋体" size="3">（注：字符集之间如果不存在子集、超集对应关系时的情况不予考虑，因为这种情况下字符集之间转换必产生乱码）</font> <font size="3"><font face="宋体"><span>&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp; 1</span>）服务器端数据库字符集与客户端应用字符集相同，与客户端<span>NLS_LANG</span>参数设置不同</font> </font><span><br />
<font face="宋体" size="3">&nbsp;&nbsp;&nbsp; </font></span><font face="宋体" size="3">如果客户端<span>NLS_LANG</span>字符集是其它两种字符集的子集，转换过程将出现乱码。</font> <span><br />
<font face="宋体" size="3">&nbsp;&nbsp;&nbsp; </font></span><font face="宋体" size="3">解决方法：将三种字符集设置成同一字符集，或<span>NLS_LANG</span>字符集是其它两种字符集的超集</font> <span><br />
<font face="宋体" size="3">&nbsp;&nbsp;&nbsp; 2</font> </span><font face="宋体" size="3">）服务器端数据库字符集与客户端<span>NLS_LANG</span>参数设置相同，与客户端应用字符集不同</font> <span><br />
<font face="宋体" size="3">&nbsp;&nbsp;&nbsp; </font></span><font face="宋体" size="3">如果客户端应用字符集是其它两种字符集的超集时，转换过程将出现乱码，但对于单字节编码存储中文问题，可参看本文第<span>5</span>章节的分析</font> <span><br />
<font face="宋体" size="3">&nbsp;&nbsp;&nbsp; 3</font> </span><font face="宋体" size="3">）客户端应用字符集、客户端<span>NLS_LANG</span>参数设置、服务器端数据库字符集互不相同</font> <span><br />
<font face="宋体" size="3">&nbsp;&nbsp; &nbsp;</font> </span><font face="宋体" size="3">此种情况较为复杂，但三种字符集之间只要有不能转换的字符，则必产生乱码</font> </p>
<p><strong><font size="3"><font face="宋体"><span>4.3</span>导入<span>/</span>导出过程出现乱码原因</font> </font></strong><span><br />
<font face="宋体" size="3">&nbsp;&nbsp;&nbsp; </font></span><font face="宋体" size="3">这个过程存在<span>4</span>个字符集设置，在<span>3.1</span>章节中已分析</font> <span><br />
<font face="宋体" size="3">&nbsp;&nbsp; </font></span><font face="宋体" size="3">（<span>1</span>）源数据库字符集</font> <span><br />
<font face="宋体" size="3">&nbsp;&nbsp; </font></span><font face="宋体" size="3">（<span>2</span>）<span>EXP</span>过程中<span>NLS_LANG</span>参数 </font><span><br />
<font face="宋体" size="3">&nbsp;&nbsp; </font></span><font face="宋体" size="3">（<span>3</span>）<span>IMP</span>过程中<span>NLS_LANG</span>参数</font> <span><br />
<font face="宋体" size="3">&nbsp;&nbsp; </font></span><font face="宋体" size="3">（<span>4</span>）目标数据库字符集</font> <span><br />
<font face="宋体" size="3">&nbsp;&nbsp;&nbsp; </font></span><font face="宋体" size="3">出现乱码原因</font> <span><br />
<font face="宋体" size="3">&nbsp;&nbsp;&nbsp; 1</font> </span><font face="宋体" size="3">）当源数据库字符集不等于<span>EXP</span>过程中<span>NLS_LANG</span>参数，且源数据库字符集是<span>EXP</span>过程中<span>NLS_LANG</span>的子集，才能保证导出文件正确，其他情况则导出文件字符乱码</font> <span><br />
<font face="宋体" size="3">&nbsp;&nbsp;&nbsp; 2</font> </span><font face="宋体" size="3">）<span>EXP</span>过程中<span>NLS_LANG</span>字符集不等于<span>IMP</span>过程中<span>NLS_LANG</span>字符集，且<span>EXP</span>过程中<span>NLS_LANG</span>字符集是<span>IMP</span>过程中<span>NLS_LANG</span>字符集的子级<span>, </span>才能保证第一次转换正常，否则第一次转换中出现乱码。</font> <span><br />
<font face="宋体" size="3">&nbsp;&nbsp;&nbsp; 3</font> </span><font face="宋体" size="3">）如果第一次转换正常，<span>IMP</span>过程中<span>NLS_LANG</span>字符集是目标数据库字符集的子集或相同，才能保证第二次转换正常，否则则第二次转换中出现乱码</font> </p>
<p><strong><font face="宋体" size="3">五．单字节编码存储中文问题</font> </strong></p>
<p><font size="3"><font face="宋体"><strong><span>&nbsp;&nbsp;&nbsp; </span></strong>由于历史的原因，早期的<span>oracle</span>没有中文字符集（如<span>oracle6</span>、<span>oracle7</span>、<span>oracle7.1</span>）<span>,</span>但有的用户从那时起就使用数据库了，并用<span>US7ASCII</span>字符集存储了中文，或是有的用户在创建数据库时，不考虑清楚，随意选择一个默认的字符集，如<span>WE8ISO8859P1</span>或<span>US7ASCII</span>，而这两个字符集都没有汉字编码，虽然有些时候选用这种字符集好象也能正常使用，但用这种字符集存储汉字信息从原则上说就是错误的，它会给数据库的使用与维护带来一系列的麻烦。</font> </font><span><br />
<font face="宋体" size="3">&nbsp;&nbsp;&nbsp; </font></span><font face="宋体" size="3">正常情况下，要将汉字存入数据库，数据库字符集必须支持中文，而将数据库字符集设置为<span>US7ASCII</span>等单字节字符集是不合适的。<span>US7ASCII</span>字符集只定义了<span>128</span>个符号，并不支持汉字。另外，如果在<span>SQL*PLUS</span>中能够输入中文，操作系统缺省应该是支持中文的，但如果在<span>NLS_LANG</span>中的字符集设置为<span>US7ASCII</span>，显然也是不正确的，它没有反映客户端的实际情况。但在实际应用中汉字显示却是正确的，这主要是因为<span>Oracle</span>检查数据库与客户端的字符集设置是同样的，那么数据在客户与数据库之间的存取过程中将不发生任何转换，但是这实际上导致了数据库标识的字符集与实际存入的内容是不相符的。而在<span>SELECT</span>的过程中，<span>Oracle</span>同样检查发现数据库与客户端的字符集设置是相同的，所以它也将存入的内容原封不动地传送到客户端，而客户端操作系统识别出这是汉字编码所以能够正确显示。</font> <span><br />
<font face="宋体" size="3">&nbsp;&nbsp;&nbsp; </font></span><font face="宋体" size="3">在这个例子中，数据库与客户端都没有设置成中文字符集，但却能正常显示中文，从应用的角度看好象没问题。然而这里面却存在着极大的隐患，比如在应用<span>length</span>或<span>substr</span>等字符串函数时，就可能得到意外的结果。</font> <span><br />
<font face="宋体" size="3">&nbsp;&nbsp;&nbsp; </font></span><font face="宋体" size="3">对于早期使用<span>US7ASCII</span>字符集数据库的数据迁移到<span>oracle8i/9i</span>中（使用<span>zhs16gbk</span>），由于原始数据已经按照<span>US7ASCII</span>格式存储，对于这种情况，可以通过使用<span>Oracle8i</span>的导出工具，设置导出字符集为<span>US7ASCII</span>，导出后使用<span>UltraEdit</span>等工具打开<span>dmp</span>文件，修改第二、三字符，修改<span> 0001 </span>为<span>0354,</span>这样就可以将<span>US7ASCII</span>字符集的数据正确导入到<span>ZHS16GBK</span>的数据库中。</font> </p>
<p><strong><font face="宋体" size="3">六．结束语</font> </strong></p>
<p><font size="3"><font face="宋体"><span>&nbsp;&nbsp;&nbsp; </span>为了避免在数据库迁移过程中由于字符集不同导致的数据损失，<span>oracle</span>提供了字符集扫描工具（<span>character set scanner</span>），通过这个工具我们可以测试在数据迁移过程中由于字符集转换可能带来的问题，然后根据测试结果，确定数据迁移过程中最佳字符集解决方案。</font></font></p>
&nbsp;
<img src ="http://www.blogjava.net/i369/aggbug/147165.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/i369/" target="_blank">芦苇</a> 2007-09-21 17:30 <a href="http://www.blogjava.net/i369/articles/147165.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>DB2使用经验备忘</title><link>http://www.blogjava.net/i369/articles/132086.html</link><dc:creator>芦苇</dc:creator><author>芦苇</author><pubDate>Tue, 24 Jul 2007 08:48:00 GMT</pubDate><guid>http://www.blogjava.net/i369/articles/132086.html</guid><wfw:comment>http://www.blogjava.net/i369/comments/132086.html</wfw:comment><comments>http://www.blogjava.net/i369/articles/132086.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/i369/comments/commentRss/132086.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/i369/services/trackbacks/132086.html</trackback:ping><description><![CDATA[1.安装DB2后可以通过命令窗口这样的命令行方式或控制中心这样的图形界面方式来操作，而如果你的数据库服务端不在本机，则还需要在&#8220;客户机配置辅助程序&#8221;中做一个客户端连接的配置。
<p>　　2.控制中心中无法增删改数据，只能编写sql语句来实现而quest提供的工具虽然能增加数据，但居然无法用复制、粘贴和Tab键，必须逐个输入，然后用<a class=10 style="COLOR: blue" href="http://product.it168.com/list/b/0220_1.shtml" target=_blank><u>鼠标</u></a>点击切换现存数据看来可以在单元格中编辑修改，但实际却无法commit，呵呵，还是老老实实写u<a class=10 style="COLOR: blue" href="http://digital.it168.com/files/zsxf.asp" target=_blank><u>pda</u></a>te语句，至于删除数据，更是非写delete语句不可。不过可以用pb以单元格方式编辑数据，相应的一个缺点是编辑数据的按钮和删除表的按钮太近，万一点错了删除表的按钮，pb可是不作提示就把表给删了的，faint</p>
<p>　　3.DB2的视图里不能直接用order by语句，必须这样写 select &#215; from(select a，b，c from table1 order by a)as　tab</p>
<p>　　这种写法的前提是你已经打过补丁了</p>
<p>　　4.<a class=10 style="COLOR: blue" href="http://storage.it168.com/" target=_blank><u>存储</u></a>过程的问题:</p>
<p>　　DB2提供ltrim函数和rtrim函数，但偏偏不提供trim函数，如果你希望去除字符两端的空格，对不起，必须用ltrim(rtrim()) 的方式调用insert 语句里面居然不能用表达式赋值，必须把值先赋给一个变量调用其他存储过程时竟然不能用常量做参数，必须把这个常量的值赋给一个变量，再以这个变量为参数</p>
<p>　　select * from table fetch first n rows only 语句居然在存储过程里不可用</p>
<p>　　5.存储过程里可以使用动态sql,但函数里却不可以使用,kao</p>
<p>　　6. 遇到commit或rollback时自动关闭游标，所以需要慎重使用单独提交。</p>
<p>　　proc builder老是在调试中<a class=10 style="COLOR: blue" href="http://product.it168.com/list/b/0205_1.shtml" target=_blank><u>内存</u></a>不足，屏幕花掉。而如果断点调试时暂停不进行下去的时间稍微长一点就会提示超时，受不了。</p>
<p>　　7.开发中遇到的一个问题</p>
<p>　　在使用 日期变量+1 MONTHS OR 日期变量-1 MONTHS 的方式取日期时，比如日期变量值为 2004-02-29时，存储过程里将日期变量+1 MONTHS 赋值给另一</p>
<p>　　日期变量时会出错。相应SQLSTATE为01506(db2 ? 01506): 对 DATE 或TIMESTAMP值进行了调整，以校正算术运算得出的无效日期。</p>
<p>　　如果要获取的只是下一月份，可采用的替代方法是获取当前日期所在月份的第一天作为基准后+1 MONTHS OR -1 MONTHS</p>
<p>　　8.哈哈,今天帮别人弄存储过程的经验@04.08.05</p>
<p>　　搞了半天搞不定，一查原来的文档才了，原来tmd该死的DB2的存储过程，是转换为C后，进行编译的。因此在数据库服务器上要安装一个C编译器才能完成存储过程的编译。并且需要使用DB2SET命令，设置DB2_SQLROUTINE_COMPILER_PATH指向C编译器的安装路径。如:db2set</p>
<p>　　DB2_SQLROUTINE_COMPILER_PATH=E:\ProgramFiles\MicrosoftVisualStudio\VC98\Bin\vcvars32.bat</p>
<p>　　9.对变量的赋值不能用select ..into ..方式而要用set v=(select ..)的方式，代码示例如下。</p>
<p>
<table style="BORDER-RIGHT: #cccccc 1px dotted; TABLE-LAYOUT: fixed; BORDER-TOP: #cccccc 1px dotted; BORDER-LEFT: #cccccc 1px dotted; BORDER-BOTTOM: #cccccc 1px dotted" cellSpacing=0 cellPadding=6 width="95%" align=center border=0>
    <tbody>
        <tr>
            <td style="WORD-WRAP: break-word" bgColor=#f3f3f3>drop function SXFM.ISORDERSUBMITDATE;<br>CREATE FUNCTION SXFM.ISORDERSUBMITDATE(IN_ROW_ID DECIMAL(16,0)) <br>&nbsp; RETURNS DATE<br>&nbsp; LANGUAGE SQL<br>BEGIN ATOMIC<br>DECLARE V_SUBMIT_DATE DATE;<br>DECLARE V_SELL_ID DECIMAL(16, 0);<br>DECLARE V_BUY_ID DECIMAL(16, 0);<br><br>set V_SELL_ID = (SELECT COALESCE(RECEIVE_ID,-1) FROM IS_ORDER WHERE ROW_ID=IN_ROW_ID);<br>set V_BUY_ID = (SELECT COALESCE(PAY_ID,-1) FROM IS_ORDER WHERE ROW_ID=IN_ROW_ID);<br>set V_SUBMIT_DATE = (SELECT DATE(MAX(A.SUBMIT_DATE)) FROM AM_AUDIT_QUEUE A,SM_USER B,SM_USER C<br>WHERE A.TABLE_CODE='IS_ORDER' AND A.TABLE_ROW_ID=IN_ROW_ID<br>AND A.AUDIT_EMP_ID=C.ROW_ID AND C.BRANCH_ID=V_BUY_ID&nbsp;&nbsp; --审核方为付款方<br>AND A.SUBMIT_EMP_ID=B.ROW_ID AND B.BRANCH_ID=V_SELL_ID); --提交方为收款方<br><br>RETURN V_SUBMIT_DATE;<br>END;<br>#SYNC 10;<br></td>
        </tr>
    </tbody>
</table>
</p>
<p>　　10.DB2的游标打开后遇到commit和rollback默认是会关闭的。保持游标打开的方法是在定义游标时加上with hold选项</p>
<p>　　11.F:导出某张表的数据，且该表包含long varchar型数据，该如何操作Q:Export:db2 con<a class=10 style="COLOR: blue" href="http://corp.it168.com/corp/88_index.shtml" target=_blank><u>nec</u></a>t to [dbname] user [user] using [password]db2move [dbname] export -tn [tablename] -u [user] -p[password] (单表)db2move [dbname] export -tn [tablename1,tablename2,...] -u [user] -p [password] (多表)Import:db2move [dbname] import</p>
<p>&nbsp;</p>
<p>=============================================================================</p>
<p><strong>DB2上机操作指令指南</strong></p>
<br>1. 启动实例(db2inst1):
<p>　　db2start</p>
<p>　　2. 停止实例(db2inst1):</p>
<p>　　db2stop</p>
<p>　　3. 列出所有实例(db2inst1)</p>
<p>　　db2ilist</p>
<p>　　5.列出当前实例:</p>
<p>　　db2 get instance</p>
<p>　　4. 察看示例配置文件:</p>
<p>　　db2 get dbm cfg|more</p>
<p>　　5. 更新数据库管理器参数信息:</p>
<p>　　db2 u<a class=10 style="COLOR: blue" href="http://digital.it168.com/files/zsxf.asp" target=_blank>pda</a>te dbm cfg using para_name para_value</p>
<p>　　6. 创建数据库:</p>
<p>　　db2 create db test</p>
<p>　　7. 察看数据库配置参数信息</p>
<p>　　db2 get db cfg for test|more</p>
<p>　　8. 更新数据库参数配置信息</p>
<p>　　db2 update db cfg for test using para_name para_value</p>
<p>　　10.删除数据库:</p>
<p>　　db2 drop db test</p>
<p>　　11.连接数据库</p>
<p>　　db2 con<a class=10 style="COLOR: blue" href="http://corp.it168.com/corp/88_index.shtml" target=_blank>nec</a>t to test</p>
<p>　　11.列出所有表空间的详细信息。</p>
<p>　　db2 list tablespaces show detail</p>
<p>　　12.列出容器的信息</p>
<p>　　db2 list tablespace containers for tbs_id show detail</p>
<p>　　13.创建表:</p>
<p>　　db2 ceate table tb1(id integer not null,name char(10))</p>
<p>　　14.列出所有表</p>
<p>　　db2 list tables</p>
<p>　　12.插入数据:</p>
<p>　　db2 insert into tb1 values(1,&#8217;sam&#8217;);</p>
<p>　　db2 insert into tb2 values(2,&#8217;smitty&#8217;);</p>
<p>　　13.查询数据:</p>
<p>　　db2 select * from tb1</p>
<p>　　14.数据:</p>
<p>　　db2 delete from tb1 where id=1</p>
<p>　　15.创建索引:</p>
<p>　　db2 create index idx1 on tb1(id);</p>
<p>　　16.创建视图:</p>
<p>　　db2 create view view1 as select id from tb1</p>
<p>　　17.查询视图:</p>
<p>