<?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>IT博客网-青蛙學堂-随笔分类-數據庫</title><link>http://www.cnitblog.com/yide/category/1876.html</link><description /><language>zh-cn</language><lastBuildDate>Mon, 08 Oct 2007 08:51:17 GMT</lastBuildDate><pubDate>Mon, 08 Oct 2007 08:51:17 GMT</pubDate><ttl>60</ttl><item><title>Trunc()</title><link>http://www.cnitblog.com/yide/archive/2007/10/08/34501.html</link><dc:creator>yide</dc:creator><author>yide</author><pubDate>Mon, 08 Oct 2007 02:12:00 GMT</pubDate><guid>http://www.cnitblog.com/yide/archive/2007/10/08/34501.html</guid><wfw:comment>http://www.cnitblog.com/yide/comments/34501.html</wfw:comment><comments>http://www.cnitblog.com/yide/archive/2007/10/08/34501.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/yide/comments/commentRss/34501.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/yide/services/trackbacks/34501.html</trackback:ping><description><![CDATA[<p>oracle trunc()函数的用法,sql,sql教程,Oracle基础 &nbsp;TRUNC()函數分兩種1.TRUNC(for dates)&nbsp; &nbsp; &nbsp; &nbsp; TRUNC函数为指定元素而截去的日期值。&nbsp; &nbsp; &nbsp; &nbsp; 其具体的语法格式如下：&nbsp; &nbsp; &nbsp; &nbsp; TRUNC（date[,fmt]）&nbsp; &nbsp; &nbsp; &nbsp; 其中：&nbsp; &nbsp; &nbsp; &nbsp; date&nbsp; &nbsp; &nbsp; &nbsp; 一个日期值&nbsp; &nbsp; &nbsp; &nbsp; fmt&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 日期格式，该日期将由指定的元素格式所截去。忽略它则由最近的日期截去&nbsp; &nbsp; &nbsp; &nbsp; 下面是该函数的使用情况：&nbsp; &nbsp; &nbsp; &nbsp; TRUNC（TO_DATE(&#8217;24-Nov-1999 08:00 pm&#8217;,&#8217;dd-mon-yyyy hh:mi am&#8217;)）&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; =&#8217;24-Nov-1999 12:00:00 am&#8217;&nbsp; &nbsp; &nbsp; &nbsp; TRUNC（TO_DATE(&#8217;24-Nov-1999 08:37 pm&#8217;,&#8217;dd-mon-yyyy hh:mi am&#8217;,&#8217;hh&#8217;)）&nbsp; &nbsp; &nbsp; &nbsp; =&#8217;24-Nov-1999 08:00:00 am&#8217;2.TRUNC(for number)&nbsp; &nbsp; &nbsp; &nbsp; TRUNC函数返回处理后的数值，其工作机制与ROUND函数极为类似，只是该函数不对指定小数前或后的部分做相应舍入选择处理，而统统截去。&nbsp; &nbsp; &nbsp; &nbsp; 其具体的语法格式如下&nbsp; &nbsp; &nbsp; &nbsp; TRUNC（number[,decimals]）&nbsp; &nbsp; &nbsp; &nbsp; 其中：&nbsp; &nbsp; &nbsp; &nbsp; number&nbsp; &nbsp; &nbsp; &nbsp; 待做截取处理的数值&nbsp; &nbsp; &nbsp; &nbsp; decimals&nbsp; &nbsp; &nbsp; &nbsp; 指明需保留小数点后面的位数。可选项，忽略它则截去所有的小数部分&nbsp; &nbsp; &nbsp; &nbsp; 下面是该函数的使用情况：&nbsp; &nbsp; &nbsp; &nbsp; TRUNC（89.985，2）=89.98&nbsp; &nbsp; &nbsp; &nbsp; TRUNC（89.985）=89&nbsp; &nbsp; &nbsp; &nbsp; TRUNC（89.985，-1）=80&nbsp; &nbsp; &nbsp; &nbsp; 注意：第二个参数可以为负数，表示为小数点左边指定位数后面的部分截去，即均以0记。 </p>
<img src ="http://www.cnitblog.com/yide/aggbug/34501.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/yide/" target="_blank">yide</a> 2007-10-08 10:12 <a href="http://www.cnitblog.com/yide/archive/2007/10/08/34501.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>sql----join</title><link>http://www.cnitblog.com/yide/archive/2007/08/06/31295.html</link><dc:creator>yide</dc:creator><author>yide</author><pubDate>Mon, 06 Aug 2007 01:53:00 GMT</pubDate><guid>http://www.cnitblog.com/yide/archive/2007/08/06/31295.html</guid><wfw:comment>http://www.cnitblog.com/yide/comments/31295.html</wfw:comment><comments>http://www.cnitblog.com/yide/archive/2007/08/06/31295.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cnitblog.com/yide/comments/commentRss/31295.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/yide/services/trackbacks/31295.html</trackback:ping><description><![CDATA[<div class=tit>sql的left join 命令详解</div>
<div class=date>2007-05-18 10:31</div>
<table style="TABLE-LAYOUT: fixed">
    <tbody>
        <tr>
            <td>
            <div class=cnt>给个通俗的解释吧. <br>例表a <br>aid adate <br>1 a1 <br>2 a2 <br>3 a3 <br>表b <br>bid bdate <br>1 b1 <br>2 b2 <br>4 b4 <br>两个表a,b相连接,要取出id相同的字段 <br>select * from a inner join b on a.aid = b.bid这是仅取出匹配的数据. <br>此时的取出的是: <br>1 a1 b1 <br>2 a2 b2 <br>那么left join 指: <br>select * from a left join b on a.aid = b.bid <br>首先取出a表中所有数据,然后再加上与a,b匹配的的数据 <br>此时的取出的是: <br>1 a1 b1 <br>2 a2 b2 <br>3 a3 空字符 <br>同样的也有right join <br>指的是首先取出b表中所有数据,然后再加上与a,b匹配的的数据 <br>此时的取出的是: <br>1 a1 b1 <br>2 a2 b2 <br>4 空字符 b4<br><br>LEFT JOIN 或 LEFT OUTER JOIN。 <br>左向外联接的结果集包括 LEFT OUTER 子句中指定的左表的所有行，而不仅仅是联接列所匹配的行。如果左表的某行在右表中没有匹配行，则在相关联的结果集行中右表的所有选择列表列均为空值。 </div>
            </td>
        </tr>
    </tbody>
</table>
<img src ="http://www.cnitblog.com/yide/aggbug/31295.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/yide/" target="_blank">yide</a> 2007-08-06 09:53 <a href="http://www.cnitblog.com/yide/archive/2007/08/06/31295.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>SNAP SHOT 01</title><link>http://www.cnitblog.com/yide/archive/2007/07/24/30491.html</link><dc:creator>yide</dc:creator><author>yide</author><pubDate>Tue, 24 Jul 2007 00:57:00 GMT</pubDate><guid>http://www.cnitblog.com/yide/archive/2007/07/24/30491.html</guid><wfw:comment>http://www.cnitblog.com/yide/comments/30491.html</wfw:comment><comments>http://www.cnitblog.com/yide/archive/2007/07/24/30491.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/yide/comments/commentRss/30491.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/yide/services/trackbacks/30491.html</trackback:ping><description><![CDATA[复制是一种实现数据分布的方法，也就是说把一个系统中的数据通过网络分布到另外一个或者多个地理位置不同的系统中，以适应可伸缩组织的需要、减轻主服务器的工作负荷和提高数据的使用效率。
<p>&nbsp;&nbsp;&nbsp; Ora Oracle8针对数据分布式计算的需要，提供了一整套功能强大的数据库复制解决方案。 Oracle8的数据复制按功能可以分为三类：基本（简单）复制、高级复制和混合复制，而高级复制又可分为多主节点复制和可更新快照复制。在 《数据复制中的定时任务机制》 介绍了Oracle8中的定时复制的机制，本文将主要介绍一个 Oracle 快照复制的实际例子及其技术实现细节。</p>
<p>&nbsp;&nbsp;&nbsp; <strong>一、业务需求<br>　</strong>在一个实际的数据库应用中，如银行、税务等商业应用中通常都采用这样一种解决方案，在一个行政区域内，如一个省或者一个市，在不同的地理位置架设数台数据库服务器，这些不同地理位置的服务器具有同样的后台数据库。为了维护数据库系统的一致性，对于整个行政区域应用的代码表应该保持一致，如果不考虑数据复制，想维护同样的不冲突的代码表是很困难的。下面是一个实际的业务需求，我们用这里例子来说明 Oracle快照复制的应用。</p>
<p>&nbsp;&nbsp;&nbsp; 为了维护整个系统代码表的一致性，客户提出了这样的业务需求，对于系统的代码表采用统一维护，即在一台服务器上维护，如图1所示。在位置1（数据库Ora_db1，用户userA）上维护代码表，其他位置（数据库ora_db2，用户userB；ora_db3，用户userC和ora_db4，用户UserD）可以直接使用这些代码表，也就是说在位置1具有对代码表插入、删除和更新的能力，而在其他地方只能有查询的能力。</p>
<p align=center><img alt="" src="http://www.stupai.com/tech/UploadPic/2006-5/200651915280390.gif" border=1 dypop="oracle复制应用实例之一"></p>
<p>&nbsp;&nbsp;<strong>&nbsp; 二、应用设计针<br>　</strong>对上述的需求，我们提出了这样一种解决方案，也就是采用 Oracle8的快照复制。具体业务实现方案设计如下：</p>
<p>&nbsp;&nbsp;&nbsp; 在位置1的数据库Ora_db1维护所有的代码表，在其余数据库建立相对于位置1的所有代码表的快照。为了维护快照的方便，在位置2、3和4创建一个单独的快照表空间和一个模式（schema），系统中的其他用户通过一个私有同义词来存取这些快照。这里私有同义词相对公共同义词要好，这是因为在位置1存在一个同样规范的系统，它的表是通过公共同义词来存取的。对于快照的刷新，采用 Oracle系统包DBMS-_REFRESH进行，并将该刷新过程的运行定时在每天早上2：00，这样可以减少网络流量。对于快照的刷新形式，由于对于代码表的维护不是很多而且代码表的数据量相对较少，所以在此选择了完全刷新，这样就避免了管理快照日志的麻烦。下面以一个节点2（ora_db2）为例来说明具体的技术实现细节。</p>
<p>&nbsp;&nbsp;&nbsp; <strong>三、技术实现细节<br>　</strong>除非特别说明，下面的SQL命令都是在数据库ora_db2的SYSETM用户下运行的。假设要复制的代码表有三个：dm_gy_rydm，dm_gy_jgdm和dm_gy_yhdm.</p>
<p>&nbsp;&nbsp;&nbsp; 1.在数据库2（ora_db2）上增加数据库1（ora_db1）的services name</p>
<p>&nbsp;&nbsp;&nbsp; 可以直接在tnsnames.ora文件中增加数据库1的services name，包括IP地址，SID以及端口号等。Services name 命名为ora_db1.world.</p>
<p>&nbsp;&nbsp;&nbsp; 2. 创建一个用于连接数据库1（ora_db1）的数据库连接（dblink）</p>
<p>&nbsp;&nbsp;&nbsp; SQL&gt; CREATE PUBLIC DATABASE LINK ora_db1.world CONNECT TO SYSTEM IDENTIFIED BY MANAGER USING 'ora_db1.world'；</p>
<p>&nbsp;&nbsp;&nbsp; 出于安全考虑，可以采用一个私有数据连接。</p>
<p>&nbsp;&nbsp;&nbsp; 3. 创建一个名为Snapshot_ts的表空间来存放快照，并创建一个和该表空间有关的名为Snap的用户。</p>
<p>&nbsp;&nbsp;&nbsp; SQL &gt; CREATE TABLESPACE snapshot_ts DATAFILE 'c：\orant\dbfiles\prod\snapshot01.dbf' SIZE 30M DEFAULT STORAGE （INITIAL 30 K NEXT 15 K MINEXTENTS 1 MAXEXTENTS 100 PCTINCREASE 0）</p>
<p>&nbsp;&nbsp;&nbsp; ONLINE PERMANENT；</p>
<p>&nbsp;&nbsp;&nbsp; SQL &gt; CREATE USER snap IDENTIFIED BY snap DEFAULT TABLESPACE snapshot_ts；</p>
<p>&nbsp;&nbsp;&nbsp; SQL &gt; GRANT CONNECT， RESOURCE TO snap；</p>
<p>&nbsp;&nbsp;&nbsp; 可以通过下面的SQL语句在ora_db1数据库以userA用户来粗略地估计表空间snapshot_ts的大小。</p>
<p>&nbsp;&nbsp;&nbsp; SQL &gt; SELECT SUM（bytes）</p>
<p>&nbsp;&nbsp;&nbsp; FROM USER_SEGMENTS WHERE SEGMENT_NAME IN（' dm_gy_rydm'，'dm_gy_jgdm'，'dm_gy_yhdm'）；</p>
<p>&nbsp;&nbsp;&nbsp; 4. 运行下面的脚本文件snapsql.sql来生成创建ora_db1数据库上userA用户下代码表的快照脚本：</p>
<p>&nbsp;&nbsp;&nbsp; /* Snapsql.sql */ spool c：\snap\create_snapshot.sql SELECT 'CREATE SNAPSHOT SNAP.' || TABLE_NAME || ' PCTFREE 10 PCTUSED 40 TABLESPACE snapshot_ts ' || ' STORAGE （INITIAL ' || INITIAL_EXTENT || ' NEXT ' || NEXT_EXTENT || ' PCTINCREASE 0 ）' || ' AS SELECT * FROM userA.' || TABLE_NAME || '@ora_db1.world</a>；' FROM USER_TABLES WHERE TABLE_NAME IN（ （' dm_gy_rydm'， 'dm_gy_jgdm'， 'dm_gy_yhdm'）； spool off</p>
<p>&nbsp;&nbsp;&nbsp; 注意上面这个生成所需表快照的脚本有一定的局限性，如果所需生成快照的表中含有类型为long的列，&#8216;select *'在这里就不会起作用，上面的这个SQL脚本就不能自动建立生成所需快照的脚本，必须通过在select列表中显式地添加long型列名来创建表的快照。下面是一个例子，假如我们要创建快照依赖的表dm_gy_note中有一个列note类型为long，就需要单独写出如下的创建快照的脚本：</p>
<p>&nbsp;&nbsp;&nbsp; CREATE SNAPSHOT snap.dm_gy_note PCTFREE 10 PCTUSED 40 TABLESPACE snapcost_ts STORAGE （INITIAL 40960 NEXT 57344 PCTINCREASE 0 ） AS SELECT dm， dmmc，note FROM userA.dm_gy_note@ora_db1.worl</a>； SQL &gt; @snapsql.sql</p>
<p>&nbsp;&nbsp;&nbsp; 5. 通过运行第4步创建的脚本文件create_snapshot.sql来创建所有的快照， 在脚本文件中包含下面这样的代码：</p>
<p>&nbsp;&nbsp;&nbsp; CREATE SNAPSHOT snap. dm_gy_rydm PCTFREE 10 PCTUSED 40 TABLESPACE snapshot_ts STORAGE （INITIAL 163840 NEXT 57344 PCTINCREASE 0）</p>
<p>&nbsp;&nbsp;&nbsp; AS SELECT * FROM userA. dm_gy_rydm @ora_db1.world；</p>
<p>&nbsp;&nbsp;&nbsp; 运行脚本文件create_snapshot.sql后，就在模式snap中创建了所需要的快照。下一步就是考虑该如何刷新快照。对于快照的刷新，可以通过一些桌面DBA工具来刷新快照也可以通过系统包dbms_snapshot.refresh来刷新一个快照：</p>
<p>&nbsp;&nbsp;&nbsp; SQL &gt; EXECUTE DBMS_SNAPSHOT.REFRESH（'snap.dm_gy_rydm'）</p>
<p>&nbsp;&nbsp;&nbsp; 6. 创建一个定时刷新过程来定时刷新快照：</p>
<p>&nbsp;&nbsp;&nbsp; /*sp_snapshot_refresh.sql */ CREATE OR REPLACE PROCEDURE sp_snapshot_refresh IS BEGIN DBMS_REFRESH.MAKE （ NAME=&gt;'tax_dmb_grp'， LIST=&gt;'snap. dm_gy_rydm， 'snap.dm_gy_jgdm'， 'snap.dm_gy_yhdm'， NEXT_DATE=&gt;TRUNC （SYSDATE+1）+2/24， INTERVAL=&gt;'（SYSDATE+1）'， IMPLICIT_DESTROY=&gt;FALSE， LAX=&gt;TRUE）； END； / SQL &gt; EXECUTE sp_snapshot_refresh</p>
<p>&nbsp;&nbsp;&nbsp; 这样就创建了一个定时任务来每天早晨2：00定时刷新快照。运行下面的SQL语句就可以看到刚刚加入的这个任务。</p>
<p>&nbsp;&nbsp;&nbsp; SQL &gt; SELECT JOB， WHAT FROM DBA_JOBS；</p>
<p>&nbsp;&nbsp;&nbsp; 7. 在用户userB下创建快照的私有同义词：</p>
<p>&nbsp;&nbsp;&nbsp; SQL &gt; CREATE SYNONYM userB.dm_gy_rydm FOR snap.dm_gy_rydm；</p>
<p>&nbsp;&nbsp;&nbsp; 8. 以Snap用户向userB用户授与快照可以select的权限。</p>
<p>&nbsp;&nbsp;&nbsp; SQL &gt; GRANT SELECT ON dm_gy_rydm TO userB；</p>
<p>&nbsp;&nbsp;&nbsp; 同样的步骤在位置3（ora_db2）和位置4（ora_db3）建立位置1（ora_db1）的代码表快照和定时刷新任务。这样就可实现在位置1统一维护代码表，在位置2、3和4使用该代码表的目的。如下面的SQL语句，在位置2（ora_db2）用户UserB浏览在位置1（ora_db1）中的代码表。</p>
<p>&nbsp;&nbsp;&nbsp; SQL &gt; SELECT * FROM dm_gy_rydm；</p>
<p>&nbsp;&nbsp;&nbsp;<strong> 四、日常维护<br>　</strong>无论任何时候只要出现网络连接问题，刷新就会失败。这些错误信息可以在alert log文件中找到。下面简单介绍一下对这种问题的处理办法：</p>
<p>&nbsp;&nbsp;&nbsp; 1. 首先在任务队列中找到刷新快照的的任务编号</p>
<p>&nbsp;&nbsp;&nbsp; SQL &gt; SELECT JOB，what FROM DBA_JOBS；</p>
<p>&nbsp;&nbsp;&nbsp; 2. 删除该任务</p>
<p>&nbsp;&nbsp;&nbsp; SQL &gt; EXECUTE DBMS_JOB.REMOVE （JOBNO）；</p>
<p>&nbsp;&nbsp;&nbsp; 3. 删除快照组</p>
<p>&nbsp;&nbsp;&nbsp; SQL &gt; EXECUTE DBMS_REFRESH.DESTROY （'tax_dmb_grp'）；</p>
<p>&nbsp;&nbsp;&nbsp; 4. 重新创建快照组并且重新定时任务来定时刷新快照</p>
<p>&nbsp;&nbsp;&nbsp; SQL &gt; EXECUTE sp_snapshot_refresh</p>
<p>&nbsp;<strong>&nbsp;&nbsp; 五、快照监视</strong></p>
<p>&nbsp;&nbsp;&nbsp; 快照可以通过下面的SQL语句来监视</p>
<p>&nbsp;&nbsp;&nbsp; SQL &gt; SELECT NAME，TO_CHAR（last_refresh，'DD-MON-YY HH：MM：SS'）</p>
<p>&nbsp;&nbsp;&nbsp; FROM DBA_SNAPSHOTS；</p>
<img src ="http://www.cnitblog.com/yide/aggbug/30491.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/yide/" target="_blank">yide</a> 2007-07-24 08:57 <a href="http://www.cnitblog.com/yide/archive/2007/07/24/30491.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>sqlserver -- 占用內存</title><link>http://www.cnitblog.com/yide/archive/2006/12/11/20358.html</link><dc:creator>yide</dc:creator><author>yide</author><pubDate>Mon, 11 Dec 2006 07:20:00 GMT</pubDate><guid>http://www.cnitblog.com/yide/archive/2006/12/11/20358.html</guid><wfw:comment>http://www.cnitblog.com/yide/comments/20358.html</wfw:comment><comments>http://www.cnitblog.com/yide/archive/2006/12/11/20358.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cnitblog.com/yide/comments/commentRss/20358.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/yide/services/trackbacks/20358.html</trackback:ping><description><![CDATA[这是SQL设计存在的问题，只有在系统的内存不够使用时，才处理SQL多余的内存；目前解决的方法就是，在企业管理器的数据库属性中，将SQL使用内存的最大数加以限制。具体:你的Server名字=〉右键=〉属性=〉内存=〉减小最大内存数量，即可。<img src ="http://www.cnitblog.com/yide/aggbug/20358.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/yide/" target="_blank">yide</a> 2006-12-11 15:20 <a href="http://www.cnitblog.com/yide/archive/2006/12/11/20358.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>sql--load</title><link>http://www.cnitblog.com/yide/archive/2006/12/11/20339.html</link><dc:creator>yide</dc:creator><author>yide</author><pubDate>Mon, 11 Dec 2006 00:59:00 GMT</pubDate><guid>http://www.cnitblog.com/yide/archive/2006/12/11/20339.html</guid><wfw:comment>http://www.cnitblog.com/yide/comments/20339.html</wfw:comment><comments>http://www.cnitblog.com/yide/archive/2006/12/11/20339.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cnitblog.com/yide/comments/commentRss/20339.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/yide/services/trackbacks/20339.html</trackback:ping><description><![CDATA[
		<p>/*******　导出到excel<br />EXEC master..xp_cmdshell 'bcp SettleDB.dbo.shanghu out c:\temp1.xls -c -q -S"GNETDATA/GNETDATA" -U"sa" -P""'</p>
		<p>/***********　导入Excel<br />SELECT * <br />FROM OpenDataSource( 'Microsoft.Jet.OLEDB.4.0',<br />　'Data Source="c:\test.xls";User ID=Admin;Password=;Extended properties=Excel 5.0')...xactions</p>
		<p>/*动态文件名<br />declare @fn varchar(20),@s varchar(1000)<br />set @fn = 'c:\test.xls'<br />set @s ='''Microsoft.Jet.OLEDB.4.0'',<br />''Data Source="'+@fn+'";User ID=Admin;Password=;Extended properties=Excel 5.0'''<br />set @s = 'SELECT * FROM OpenDataSource ('+@s+')...sheet1$'<br />exec(@s)<br />*/</p>
		<p>SELECT cast(cast(科目编号 as numeric(10,2)) as nvarchar(255))+'　' 转换后的别名<br />FROM OpenDataSource( 'Microsoft.Jet.OLEDB.4.0',<br />　'Data Source="c:\test.xls";User ID=Admin;Password=;Extended properties=Excel 5.0')...xactions</p>
		<p>/********************** EXCEL导到远程SQL<br />insert OPENDATASOURCE(<br />　　　　 'SQLOLEDB',<br />　　　　 'Data Source=远程ip;User ID=sa;Password=密码'<br />　　　　 ).库名.dbo.表名 (列名1,列名2)<br />SELECT 列名1,列名2<br />FROM OpenDataSource( 'Microsoft.Jet.OLEDB.4.0',<br />　'Data Source="c:\test.xls";User ID=Admin;Password=;Extended properties=Excel 5.0')...xactions</p>
		<p>
				<br />/** 导入文本文件<br />EXEC master..xp_cmdshell 'bcp dbname..tablename in c:\DT.txt -c -Sservername -Usa -Ppassword'</p>
		<p>/** 导出文本文件<br />EXEC master..xp_cmdshell 'bcp dbname..tablename out c:\DT.txt -c -Sservername -Usa -Ppassword'<br />或<br />EXEC master..xp_cmdshell 'bcp "Select * from dbname..tablename" queryout c:\DT.txt -c -Sservername -Usa -Ppassword'</p>
		<p>导出到TXT文本，用逗号分开<br />exec master..xp_cmdshell 'bcp "库名..表名" out "d:\tt.txt" -c -t ,-U sa -P password'</p>
		<p>
				<br />BULK INSERT 库名..表名<br />FROM 'c:\test.txt'<br />WITH (<br />　　FIELDTERMINATOR = ';',<br />　　ROWTERMINATOR = '\n'<br />)</p>
		<p>
				<br />--/* dBase IV文件<br />select * from <br />OPENROWSET('MICROSOFT.JET.OLEDB.4.0'<br />,'dBase IV;HDR=NO;IMEX=2;DATABASE=C:\','select * from [客户资料4.dbf]')<br />--*/</p>
		<p>--/* dBase III文件<br />select * from <br />OPENROWSET('MICROSOFT.JET.OLEDB.4.0'<br />,'dBase III;HDR=NO;IMEX=2;DATABASE=C:\','select * from [客户资料3.dbf]')<br />--*/</p>
		<p>--/* FoxPro 数据库<br />select * from openrowset('MSDASQL',<br />'Driver=Microsoft Visual FoxPro Driver;SourceType=DBF;SourceDB=c:\',<br />'select * from [aa.DBF]')<br />--*/</p>
		<p>/**************导入DBF文件****************/<br />select * from openrowset('MSDASQL',<br />'Driver=Microsoft Visual FoxPro Driver;<br />SourceDB=e:\VFP98\data;<br />SourceType=DBF',<br />'select * from customer where country != "USA" order by country')<br />go<br />/***************** 导出到DBF ***************/<br />如果要导出数据到已经生成结构(即现存的)FOXPRO表中,可以直接用下面的SQL语句</p>
		<p>insert into openrowset('MSDASQL',<br />'Driver=Microsoft Visual FoxPro Driver;SourceType=DBF;SourceDB=c:\',<br />'select * from [aa.DBF]')<br />select * from 表</p>
		<p>说明:<br />SourceDB=c:\　指定foxpro表所在的文件夹<br />aa.DBF　　　　指定foxpro表的文件名.</p>
		<p>
		</p>
		<p>
				<br />/*************导出到Access********************/<br />insert into openrowset('Microsoft.Jet.OLEDB.4.0', <br />　 'x:\A.mdb';'admin';'',A表) select * from 数据库名..B表</p>
		<p>/*************导入Access********************/<br />insert into B表 selet * from openrowset('Microsoft.Jet.OLEDB.4.0', <br />　 'x:\A.mdb';'admin';'',A表)</p>
		<p>文件名为参数<br />declare @fname varchar(20)<br />set @fname = 'd:\test.mdb'<br />exec('SELECT a.* FROM opendatasource(''Microsoft.Jet.OLEDB.4.0'',<br />　　'''+@fname+''';''admin'';'''', topics) as a ')</p>
		<p>SELECT * <br />FROM OpenDataSource( 'Microsoft.Jet.OLEDB.4.0',<br />　'Data Source="f:\northwind.mdb";Jet OLEDB:Database Password=123;User ID=Admin;Password=;')...产品</p>
		<p>*********************　导入 xml　文件</p>
		<p>DECLARE @idoc int<br />DECLARE @doc varchar(1000)<br />--sample XML document<br />SET @doc ='<br />&lt;root&gt;<br />　&lt;Customer cid= "C1" name="Janine" city="Issaquah"&gt;<br />　　　&lt;Order oid="O1" date="1/20/1996" amount="3.5" /&gt;<br />　　　&lt;Order oid="O2" date="4/30/1997" amount="13.4"&gt;Customer was very satisfied<br />　　　&lt;/Order&gt;<br />　 &lt;/Customer&gt;<br />　 &lt;Customer cid="C2" name="Ursula" city="Oelde" &gt;<br />　　　&lt;Order oid="O3" date="7/14/1999" amount="100" note="Wrap it blue <br />　　　　　　 white red"&gt;<br />　　　　　　&lt;Urgency&gt;Important&lt;/Urgency&gt;<br />　　　　　　Happy Customer.<br />　　　&lt;/Order&gt;<br />　　　&lt;Order oid="O4" date="1/20/1996" amount="10000"/&gt;<br />　 &lt;/Customer&gt;<br />&lt;/root&gt;<br />'<br />-- Create an internal representation of the XML document.<br />EXEC sp_xml_preparedocument @idoc OUTPUT, @doc</p>
		<p>-- Execute a SELECT statement using OPENXML rowset provider.<br />SELECT *<br />FROM OPENXML (@idoc, '/root/Customer/Order', 1)<br />　　　WITH (oid　　 char(5), <br />　　　　　　amount　float, <br />　　　　　　comment ntext 'text()')<br />EXEC sp_xml_removedocument @idoc</p>
		<p>
		</p>
		<p>???????</p>
		<p>/**********************Excel导到Txt****************************************/<br />想用<br />select * into opendatasource(...) from opendatasource(...)<br />实现将一个Excel文件内容导入到一个文本文件</p>
		<p>假设Excel中有两列，第一列为姓名，第二列为很行帐号(16位)<br />且银行帐号导出到文本文件后分两部分，前8位和后8位分开。</p>
		<p>
				<br />邹健：<br />如果要用你上面的语句插入的话,文本文件必须存在,而且有一行:姓名,银行账号1,银行账号2<br />然后就可以用下面的语句进行插入<br />注意文件名和目录根据你的实际情况进行修改.</p>
		<p>insert into<br />opendatasource('MICROSOFT.JET.OLEDB.4.0'<br />,'Text;HDR=Yes;DATABASE=C:\'<br />)...[aa#txt]<br />--,aa#txt)<br />--*/<br />select 姓名,银行账号1=left(银行账号,8),银行账号2=right(银行账号,8) <br />from <br />opendatasource('MICROSOFT.JET.OLEDB.4.0'<br />,'Excel 5.0;HDR=YES;IMEX=2;DATABASE=c:\a.xls'<br />--,Sheet1$)<br />)...[Sheet1$]</p>
		<p>
		</p>
		<p>如果你想直接插入并生成文本文件,就要用bcp</p>
		<p>declare @sql varchar(8000),@tbname varchar(50)</p>
		<p>--首先将excel表内容导入到一个全局临时表<br />select @tbname='[##temp'+cast(newid() as varchar(40))+']'<br />,@sql='select 姓名,银行账号1=left(银行账号,8),银行账号2=right(银行账号,8) <br />into '+@tbname+' from <br />opendatasource(''MICROSOFT.JET.OLEDB.4.0''<br />,''Excel 5.0;HDR=YES;IMEX=2;DATABASE=c:\a.xls''<br />)...[Sheet1$]'<br />exec(@sql)</p>
		<p>--然后用bcp从全局临时表导出到文本文件<br />set @sql='bcp "'+@tbname+'" out "c:\aa.txt" /S"(local)" /P"" /c'<br />exec master..xp_cmdshell @sql</p>
		<p>--删除临时表<br />exec('drop table '+@tbname)</p>
		<p>
				<br />/********************导整个数据库*********************************************/</p>
		<p>用bcp实现的存储过程</p>
		<p>
				<br />/*<br />实现数据导入/导出的存储过程<br />　　　　 根据不同的参数,可以实现导入/导出整个数据库/单个表<br />调用示例:<br />--导出调用示例<br />----导出单个表<br />exec file2table 'zj','','','xzkh_sa..地区资料','c:\zj.txt',1<br />----导出整个数据库<br />exec file2table 'zj','','','xzkh_sa','C:\docman',1</p>
		<p>--导入调用示例<br />----导入单个表<br />exec file2table 'zj','','','xzkh_sa..地区资料','c:\zj.txt',0<br />----导入整个数据库<br />exec file2table 'zj','','','xzkh_sa','C:\docman',0</p>
		<p>*/<br />if exists(select 1 from sysobjects where name='File2Table' and objectproperty(id,'IsProcedure')=1)<br />drop procedure File2Table<br />go<br />create procedure File2Table<br />@servername varchar(200)　--服务器名<br />,@username varchar(200)　 --用户名,如果用NT验证方式,则为空''<br />,@password varchar(200)　 --密码<br />,@tbname varchar(500)　 --数据库.dbo.表名,如果不指定:.dbo.表名,则导出数据库的所有用户表<br />,@filename varchar(1000)　--导入/导出路径/文件名,如果@tbname参数指明是导出整个数据库,则这个参数是文件存放路径,文件名自动用表名.txt<br />,@isout bit　　　--1为导出,0为导入<br />as<br />declare @sql varchar(8000)</p>
		<p>if @tbname like '%.%.%' --如果指定了表名,则直接导出单个表<br />begin<br />set @sql='bcp '+@tbname<br />　+case when @isout=1 then ' out ' else ' in ' end<br />　+' "'+@filename+'" /w'<br />　+' /S '+@servername<br />　+case when isnull(@username,'')='' then '' else ' /U '+@username end<br />　+' /P '+isnull(@password,'')<br />exec master..xp_cmdshell @sql<br />end<br />else<br />begin --导出整个数据库,定义游标,取出所有的用户表<br />declare @m_tbname varchar(250)<br />if right(@filename,1)&lt;&gt;'\' set @filename=@filename+'\'</p>
		<p>set @m_tbname='declare #tb cursor for select name from '+@tbname+'..sysobjects where xtype=''U'''<br />exec(@m_tbname)<br />open #tb<br />fetch next from #tb into @m_tbname<br />while @@fetch_status=0<br />begin<br />　set @sql='bcp '+@tbname+'..'+@m_tbname<br />　 +case when @isout=1 then ' out ' else ' in ' end<br />　 +' "'+@filename+@m_tbname+'.txt " /w'<br />　 +' /S '+@servername<br />　 +case when isnull(@username,'')='' then '' else ' /U '+@username end<br />　 +' /P '+isnull(@password,'')<br />　exec master..xp_cmdshell @sql<br />　fetch next from #tb into @m_tbname<br />end<br />close #tb<br />deallocate #tb <br />end<br />go</p>
		<p>
				<br />/************* Oracle **************/<br />EXEC sp_addlinkedserver 'OracleSvr', <br />　 'Oracle 7.3', <br />　 'MSDAORA', <br />　 'ORCLDB'<br />GO</p>
		<p>delete from openquery(mailser,'select *　from yulin')</p>
		<p>select *　from openquery(mailser,'select *　from yulin')</p>
		<p>update openquery(mailser,'select * from　yulin where id=15')set disorder=555,catago=888</p>
		<p>insert into openquery(mailser,'select disorder,catago from　yulin')values(333,777)</p>
		<p>
		</p>
		<p>补充：</p>
		<p>对于用bcp导出,是没有字段名的.</p>
		<p>用openrowset导出,需要事先建好表.</p>
		<p>用openrowset导入,除ACCESS及EXCEL外,均不支持非本机数据导入</p>
		<br />
<img src ="http://www.cnitblog.com/yide/aggbug/20339.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/yide/" target="_blank">yide</a> 2006-12-11 08:59 <a href="http://www.cnitblog.com/yide/archive/2006/12/11/20339.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>導入數據 oracle</title><link>http://www.cnitblog.com/yide/archive/2006/12/11/20337.html</link><dc:creator>yide</dc:creator><author>yide</author><pubDate>Mon, 11 Dec 2006 00:53:00 GMT</pubDate><guid>http://www.cnitblog.com/yide/archive/2006/12/11/20337.html</guid><wfw:comment>http://www.cnitblog.com/yide/comments/20337.html</wfw:comment><comments>http://www.cnitblog.com/yide/archive/2006/12/11/20337.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/yide/comments/commentRss/20337.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/yide/services/trackbacks/20337.html</trackback:ping><description><![CDATA[大型的数据库开发中常常遇到数据源是平面文件（如文本文件）的情况，对于这样的数据源，无法使用数据库对其数据进行有效的管理，另外也无法使用SQL语句对其进行查询和操作，所以当务之急就是将这些平面文件导 
<p>　　入到数据库中，然后就可以对其进行高效的操作了。</p><p>　　下面介绍几种常见的数据导入的方法，希望能够给大家启迪。另外，本文所涉及到的数据库均为ORACLE数据库，其实对于其他数据库而言，方法类似。</p><p>　　<strong>一、Sql*:Loader</strong></p><p>　　该方法是Oracle数据库下数据导入的最重要的方法之一，该工具由Oracle客户端提供，其基本工作原理是：首先要针对数据源文件制作一个控制文件，控制文件是用来解释如何对源文件进行解析，其中需要包含源文件的数据格式、目标数据库的字段等信息，一个典型的控制文件为如下形式：<br />LOAD DATA <br />    INFILE  '/ora9i/fengjie/agent/data/ipaagentdetail200410.txt'     <br />    TRUNCATE<br />    INTO TABLE fj_ipa_agentdetail<br />    fields terminated ","<br />    trailing nullcols<br />(  AGENT_NO       char, <br />  AGENT_NAME     char, <br />  AGENT_ADDRESS  char, <br />  AGENT_LINKNUM  char, <br />  AGENT_LINKMAN  char           <br />)</p><p>其中，INFILE  '/ora9i/fengjie/agent/data/ipaagentdetail200410.txt'指明所要导入的源文件，其实源文件也可以直接通过命令行来输入获得  <br />，fj_ipa_agentdetail为目标表的名字，fields terminated ","是指源文件的各个字段是以逗号分隔，trailing nullcols表示遇到空字段依然写入到数据库表中，最后这５个字段是目标数据库表的字段结构。通过上面这个典型的控制文件的格式分析可知，控制文件需要与源文件的格式信息一致，否则导入数据会出现异常。<br />除了控制以外，sql*loader的还需要数据文件，即源文件。根据格式的不同，源文件可以分为固定字段长度和有分隔符这两大类，这里将分别说明这两种情况： </p><p><br />固定字段长度的文本文件<br />就是每个字段拥有固定的字段长度，比如：<br />602530005922        1012<br />602538023138        1012<br />602536920355        1012<br />602531777166        1012<br />602533626494        1012<br />602535700601        1012</p><p>有分隔符的文本文件<br />就是每个字段都有相同的分隔符分隔，比如：</p><p>1001,上海长途电信综合开发公司,南京东路34号140室<br />1002,上海桦奇通讯科技有限公司,武宁路19号1902室 <br />1003,上海邦正科技发展有限公司,南京东路61号903室</p><p>　　对于上述两种文件格式sql*loader均可以做处理，下面就前面那个固定长度的文本来举例说明：<br />由于该文本只有两个字段，一个为设备号，一个是区局编号，两者的长度分别为２０和５，那么可以　　　编制控制文件如下：<br />LOAD DATA <br />    INFILE  '/ora9i/fengjie/agent/data/ipaagent200410.txt' <br />    TRUNCATE<br />    INTO TABLE fj_ipa_agent<br />(         DEVNO      POSITION(1:20) CHAR,<br />          BRANCH_NO    POSITION(21:25) CHAR         <br />)<br />　　其中，'/ora9i/fengjie/agent/data/ipaagent200410.txt'为该文件的完全路径，POSITION(M:N)表示该字段是从位置M到位置N。</p><p>　　对于有分隔符的数据文件，前面已经有一个例子，这里就不再赘述了。总之，使用Sql*Loader能够轻松将数据文件导入到数据库中，这种方法也是最常用的方法。</p><p>　　<strong>二、 使用专业的数据抽取工具</strong></p><p>　　目前在数据仓库领域中，数据抽取与装载（ETL）是一重要的技术，这一技术对于一些大的数据文件或者文件数量较多尤其适合。这里简单介绍目前一款主流的数据抽取工具――Informatica。</p><p>　　该工具主要采用图形界面进行编程，其主要工作流程是：首先将源数据文件的结构（格式）导入为Informatica里，然后根据业务规则对该结构进行一定的转换(transformation)，最终导入到目标表中。</p><p>　　以上过程仅仅只是做了一个从源到目标的映射，数据的实际抽取与装载需要在工作流（workflow）里进行。</p><p>　　使用专业的数据抽取工具，可以结合业务逻辑对多个源数据进行join,union,insect等操作，适合于大型数据库和数据仓库。</p><p>　　<strong>三、 使用Access工具导入</strong></p><p>　　可以直接在Access里选择‘打开‘文本文件，这样按照向导来导入一个文本文件到Access数据库中，然后使用编程的方法将其导入到最终的目标数据库中。</p><p>　　这种方法虽然烦琐，但是其对系统的软件配置要求相对较低，所以也是有一定的使用范围。</p><p>　　<strong>四、 小结</strong></p><p>　　总之，平面文件转化为数据库格式有利于数据的处理，显然，数据库强大的数据处理能力比直接进行文件I/O效率高出很多，希望本文能够对该领域做一个抛砖引玉的作用。</p><br /><img src ="http://www.cnitblog.com/yide/aggbug/20337.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/yide/" target="_blank">yide</a> 2006-12-11 08:53 <a href="http://www.cnitblog.com/yide/archive/2006/12/11/20337.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>SQL 取相等部分 </title><link>http://www.cnitblog.com/yide/archive/2006/09/13/16791.html</link><dc:creator>yide</dc:creator><author>yide</author><pubDate>Wed, 13 Sep 2006 08:37:00 GMT</pubDate><guid>http://www.cnitblog.com/yide/archive/2006/09/13/16791.html</guid><wfw:comment>http://www.cnitblog.com/yide/comments/16791.html</wfw:comment><comments>http://www.cnitblog.com/yide/archive/2006/09/13/16791.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/yide/comments/commentRss/16791.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/yide/services/trackbacks/16791.html</trackback:ping><description><![CDATA[ORACLE   :<br /><br />        SELECT  T1.C1 , T2.C2    FROM  T1 , T2<br />       WHERE   T1.C3 (+) = T2.C3 <img src ="http://www.cnitblog.com/yide/aggbug/16791.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/yide/" target="_blank">yide</a> 2006-09-13 16:37 <a href="http://www.cnitblog.com/yide/archive/2006/09/13/16791.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Procedure</title><link>http://www.cnitblog.com/yide/archive/2006/05/16/10596.html</link><dc:creator>yide</dc:creator><author>yide</author><pubDate>Tue, 16 May 2006 05:51:00 GMT</pubDate><guid>http://www.cnitblog.com/yide/archive/2006/05/16/10596.html</guid><wfw:comment>http://www.cnitblog.com/yide/comments/10596.html</wfw:comment><comments>http://www.cnitblog.com/yide/archive/2006/05/16/10596.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/yide/comments/commentRss/10596.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/yide/services/trackbacks/10596.html</trackback:ping><description><![CDATA[
		<p>
				<font face="verdana, arial, helvetica" size="2">
						<span class="javascript" id="text1691325" style="FONT-SIZE: 12px">返回记录集过程:<br />CREATE OR REPLACE PACKAGE pkg_test<br />AS<br />TYPE myrctype IS REF CURSOR;<br /><br />PROCEDURE get (p_id NUMBER, p_rc OUT myrctype);<br />END pkg_test;<br />/<br /><br />CREATE OR REPLACE PACKAGE BODY pkg_test<br />AS<br />PROCEDURE get (p_id NUMBER, p_rc OUT myrctype)<br />IS<br />sqlstr VARCHAR2 (500);<br />BEGIN<br />IF p_id = 0 THEN<br />OPEN p_rc FOR<br />SELECT ID, NAME, sex, address, postcode, birthday<br />FROM student;<br />ELSE<br />sqlstr :=<br />'select id,name,sex,address,postcode,birthday<br />from student where id=:w_id';<br />OPEN p_rc FOR sqlstr USING p_id;<br />END IF;<br />END get;<br />END pkg_test;<br />/<br />--------------------------------------------------------------------------------------------------------------<br />返回记录集函数:<br />1、建立测试表<br />CREATE TABLE student<br />(<br />id NUMBER,<br />name VARCHAR2(30),<br />sex VARCHAR2(10),<br />address VARCHAR2(100),<br />postcode VARCHAR2(10),<br />birthday DATE,<br />photo LONG RAW<br />);<br />/<br /><br />2、建立带ref cursor定义的包和包体及函数：<br />CREATE OR REPLACE<br />package pkg_test as<br />/* 定义ref cursor类型<br />不加return类型，为弱类型，允许动态sql查询，<br />否则为强类型，无法使用动态sql查询;<br />*/<br />type myrctype is ref cursor; <br /><br />--函数申明<br />function get(intID number) return myrctype;<br />end pkg_test;<br />/<br /><br />CREATE OR REPLACE<br />package body pkg_test as<br />--函数体<br />function get(intID number) return myrctype is<br />rc myrctype; --定义ref cursor变量<br />sqlstr varchar2(500);<br />begin<br />if intID=0 then<br />--静态测试，直接用select语句直接返回结果<br />open rc for select id,name,sex,address,postcode,birthday from student;<br />else<br />--动态sql赋值，用:w_id来申明该变量从外部获得<br />sqlstr := 'select id,name,sex,address,postcode,birthday from student where id=:w_id';<br />--动态测试，用sqlstr字符串返回结果，用using关键词传递参数<br />open rc for sqlstr using intid;<br />end if;<br /><br />return rc;<br />end get;<br /><br />end pkg_test;<br />/<br /><br />3、用pl/sql块进行测试：<br />declare<br />w_rc pkg_test.myrctype; --定义ref cursor型变量<br /><br />--定义临时变量，用于显示结果<br />w_id student.id%type;<br />w_name student.name%type;<br />w_sex student.sex%type;<br />w_address student.address%type;<br />w_postcode student.postcode%type;<br />w_birthday student.birthday%type;<br /><br />begin<br />--调用函数，获得记录集<br />w_rc := pkg_test.get(1);<br /><br />--fetch结果并显示<br />loop<br />fetch w_rc into w_id,w_name,w_sex,w_address,w_postcode,w_birthday;<br />exit when w_rc%notfound;<br />dbms_output.put_line(w_name);<br />end loop;<br />end;<br /><br />4、测试结果：<br />通过。<br />--------------------------------------------------------------------------------------------------------------<br />返回对象类型:<br />SQL&gt; create table a (id number,name varchar2(50),doctime date);<br /><br />Table created.<br /><br />--插入六条测试数据：<br />SQL&gt; insert into a values (1,'aaa',to_date('2002-07-01','yyyy-mm-dd'));<br /><br />1 row created.<br /><br />SQL&gt; insert into a values (2,'bbb',to_date('2002-07-02','yyyy-mm-dd'));<br /><br />1 row created.<br /><br />SQL&gt; insert into a values (3,'ccc',to_date('2002-07-03','yyyy-mm-dd'));<br /><br />1 row created.<br /><br />SQL&gt; insert into a values (4,'ddd',to_date('2002-07-04','yyyy-mm-dd'));<br /><br />1 row created.<br /><br />SQL&gt; insert into a values (5,'eee',to_date('2002-07-05','yyyy-mm-dd'));<br /><br />1 row created.<br /><br />SQL&gt; insert into a values (6,'fff',to_date('2002-07-06','yyyy-mm-dd'));<br /><br />1 row created.<br /><br />SQL&gt; commit;<br /><br />Commit complete.<br /><br />--创建两个type<br />SQL&gt; create or replace type myobjectype as object (x int,y date,z varchar2(50));<br />2 /<br /><br />Type created.<br /><br />SQL&gt; create or replace type mytabletype as table of myobjectype<br />2 /<br /><br />Type created.<br /><br />--创建可以返回纪录集的函数(不传入表名参数)<br />SQL&gt; create or replace function testrerecordnotabname (tableid in number)<br />2 return mytabletype<br />3 as<br />4 l_data mytabletype :=mytabletype();<br />5 begin<br />6 for i in (select * from a where id&gt;=tableid) loop<br />7 l_data.extend;<br />8 l_data(l_data.count) := myobjectype(i.id,i.doctime,i.name);<br />9 exit when i.id = 62;<br />10 end loop; <br />11 return l_data; <br />12 end; <br />13 /<br /><br />Function created.<br /><br />SQL&gt; commit;<br /><br />Commit complete.<br /><br />--创建可以返回纪录集的函数(可以传入表名参数)<br />SQL&gt; create or replace function testrerecordtabname (tablename in varchar2,tableid in number)<br />2 return mytabletype<br />3 as<br />4 l_data mytabletype :=mytabletype();<br />5 strsql varchar2(50);<br />6 type v_cursor is ref cursor;<br />7 v_tempcursor v_cursor;<br />8 i1 number;<br />9 i2 varchar2(50);<br />10 i3 date;<br />11 begin<br />12 strsql := 'select * from ' || tablename || ' where id&gt;=' || tableid;<br />13 open v_tempcursor for strsql;<br />14 loop <br />15 fetch v_tempcursor into i1,i2,i3;<br />16 l_data.extend;<br />17 l_data(l_data.count) := myobjectype(i1,i3,i2);<br />18 exit when v_tempcursor%NOTFOUND;<br />19 end loop; <br />20 return l_data; <br />21 end; <br />22 /<br /><br />Function created.<br /><br />SQL&gt; commit;<br /><br />Commit complete.<br /><br />--测试不传表名参数的function(testrerecorenotabname)<br />SQL&gt; set serveroutput on <br />SQL&gt; declare<br />2 testre mytabletype :=mytabletype();<br />3 i number :=0;<br />4 begin<br />5 testre := testrerecordnotabname(1);<br />6 loop<br />7 i := i+1;<br />8 dbms_output.put_line(';' || testre(i).x || ';' || testre(i).y || ';' || testre(i).z || ';');<br />9 exit when i = testre.count;<br />10 end loop;<br />11 end;<br />12 /<br />;1;01-7?? -02;aaa;<br />;2;02-7?? -02;bbb;<br />;3;03-7?? -02;ccc;<br />;4;04-7?? -02;ddd;<br />;5;05-7?? -02;eee;<br />;6;06-7?? -02;fff;<br /><br />PL/SQL procedure successfully completed.<br /><br />--测试传表名参数的function(testrerecoretabname)<br />SQL&gt; set serveroutput on <br />SQL&gt; declare<br />2 testre mytabletype :=mytabletype();<br />3 i number :=0;<br />4 begin<br />5 testre := testrerecordtabname('a',1);<br />6 loop<br />7 i := i+1;<br />8 dbms_output.put_line(';' || testre(i).x || ';' || testre(i).y || ';' || testre(i).z || ';');<br />9 exit when i = testre.count;<br />10 end loop;<br />11 end;<br />12 /<br />;1;01-7?? -02;aaa;<br />;2;02-7?? -02;bbb;<br />;3;03-7?? -02;ccc;<br />;4;04-7?? -02;ddd;<br />;5;05-7?? -02;eee;<br />;6;06-7?? -02;fff;<br />;6;06-7?? -02;fff;<br /><br />PL/SQL procedure successfully completed.<br />--------------------------------------------------------------------------------------------------------------<br />利用对象类型通过字符串分析出数据函数:<br />create or replace type mytabletype as table of number;<br />/<br /><br />create or replace function strtab(p_str in varchar2)<br />return mytabletype<br />as<br />lstr varchar2(1000) default p_str||',';<br />ln number;<br />ldata mytabletype:=mytabletype();<br />begin<br />loop<br />ln:=instr(lstr,',');<br />exit when (nvl(ln,0)=0);<br />ldata.extend;<br />ldata(ldata.count):=ltrim(rtrim(substr(lstr,1,ln-1)));<br />lstr:=substr(lstr,ln+1);<br />end loop;<br />return ldata;<br />end;<br />/<br /><br />SQL&gt; select * from table(cast(strtab('11,12,13') as mytabletype));<br /><br />COLUMN_VALUE<br />------------<br />11<br />12<br />13<br /><br />SQL&gt; create table bb(id varchar2(2),name varchar2(10));<br /><br />Table created<br /><br />SQL&gt; insert into bb values('11','张三');<br /><br />1 row inserted<br /><br />SQL&gt; insert into bb values('12','李四');<br /><br />1 row inserted<br /><br />SQL&gt; insert into bb values('13','王五');<br /><br />1 row inserted<br /><br />SQL&gt; select * from bb where id in (select * from table(cast(strtab('11,12,13') as mytabletype)));<br /><br />ID NAME<br />-- ----------<br />11 张三<br />12 李四<br />13 王五<br />------------------------------------------------------------------------------------------------------------------<br />字段类型为嵌套表的使用方法:<br />CREATE TYPE Course AS OBJECT (<br />course_no NUMBER(4), <br />title VARCHAR2(35),<br />credits NUMBER(1));<br />/<br /><br />CREATE TYPE CourseList AS TABLE OF Course;<br />/<br /><br />CREATE TABLE division (<br />name VARCHAR2(20),<br />director VARCHAR2(20),<br />office VARCHAR2(20),<br />courses CourseList) <br />NESTED TABLE courses STORE AS courses_tab;<br /><br /><br />INSERT INTO division<br />VALUES('Psychology', 'Irene Friedman', 'Fulton Hall 133',<br />CourseList(Course(1000, 'General Psychology', 5),<br />Course(2100, 'Experimental Psychology', 4),<br />Course(2200, 'Psychological Tests', 3),<br />Course(2250, 'Behavior Modification', 4),<br />Course(3540, 'Groups and Organizations', 3),<br />Course(3552, 'Human Factors in the Workplace', 4),<br />Course(4210, 'Theories of Learning', 4),<br />Course(4320, 'Cognitive Processes', 4),<br />Course(4410, 'Abnormal Psychology', 4)));<br />INSERT INTO division<br />VALUES('History', 'John Whalen', 'Applegate Hall 142',<br />CourseList(Course(1011, 'History of Europe I', 4),<br />Course(1012, 'History of Europe II', 4),<br />Course(1202, 'American History', 5),<br />Course(2130, 'The Renaissance', 3),<br />Course(2132, 'The Reformation', 3),<br />Course(3105, 'History of Ancient Greece', 4),<br />Course(3321, 'Early Japan', 4),<br />Course(3601, 'Latin America Since 1825', 4),<br />Course(3702, 'Medieval Islamic History', 4)));<br />INSERT INTO division<br />VALUES('English', 'Lynn Saunders', 'Breakstone Hall 205',<br />CourseList(Course(1002, 'Expository Writing', 3),<br />Course(2020, 'Film and Literature', 4),<br />Course(2418, 'Modern Science Fiction', 3),<br />Course(2810, 'Discursive Writing', 4),<br />Course(3010, 'Modern English Grammar', 3),<br />Course(3720, 'Introduction to Shakespeare', 4),<br />Course(3760, 'Modern Drama', 4),<br />Course(3822, 'The Short Story', 4),<br />Course(3870, 'The American Novel', 5)));<br />----------------------------------------------------------------------------------------------------------------<br />游标只是plsql中使用的变量并不是oracle的对象，所以它不能在过程或函数间进行传递。<br />下面的方法是通过table类型的对象来存储要返回的记录集。<br />--创建测试表：<br />SQL&gt; create table a (id number,name varchar2(50),doctime date);<br /><br />Table created.<br /><br />--插入六条测试数据：<br />SQL&gt; insert into a values (1,'aaa',to_date('2002-07-01','yyyy-mm-dd'));<br /><br />1 row created.<br /><br />SQL&gt; insert into a values (2,'bbb',to_date('2002-07-02','yyyy-mm-dd'));<br /><br />1 row created.<br /><br />SQL&gt; insert into a values (3,'ccc',to_date('2002-07-03','yyyy-mm-dd'));<br /><br />1 row created.<br /><br />SQL&gt; insert into a values (4,'ddd',to_date('2002-07-04','yyyy-mm-dd'));<br /><br />1 row created.<br /><br />SQL&gt; insert into a values (5,'eee',to_date('2002-07-05','yyyy-mm-dd'));<br /><br />1 row created.<br /><br />SQL&gt; insert into a values (6,'fff',to_date('2002-07-06','yyyy-mm-dd'));<br /><br />1 row created.<br /><br />SQL&gt; commit;<br /><br />Commit complete.<br /><br />--创建两个type<br />SQL&gt; create or replace type myobjectype as object (x int,y date,z varchar2(50));<br />2 /<br /><br />Type created.<br /><br />SQL&gt; create or replace type mytabletype as table of myobjectype<br />2 /<br /><br />Type created.<br /><br />--创建可以返回纪录集的过程<br />SQL&gt; create or replace procedure testrerecordnotabname (tableid in number, l_data out mytabletype)<br />2 <br />3 as<br />4 <br />5 begin<br />6 for i in (select * from a where id&gt;=tableid) loop<br />7 l_data.extend;<br />8 l_data(l_data.count) := myobjectype(i.id,i.doctime,i.name);<br />9 exit when i.id = 62;<br />10 end loop; <br />11 <br />12 end; <br />13 /<br /><br />Function created.<br /><br />SQL&gt; commit;<br /><br />Commit complete.<br /><br />SQL&gt; commit;<br /><br />Commit complete.<br /><br />--测试不传表名参数的procedure(testrerecorenotabname)<br />SQL&gt; set serveroutput on <br />SQL&gt; declare<br />2 testre mytabletype :=mytabletype();<br />3 i number :=0;<br />4 begin<br />5 testrerecordnotabname(1,testre);<br />6 loop<br />7 i := i+1;<br />8 dbms_output.put_line(';' || testre(i).x || ';' || testre(i).y || ';' || testre(i).z || ';');<br />9 exit when i = testre.count;<br />10 end loop;<br />11 end;<br />12 /<br />;1;01-7?? -02;aaa;<br />;2;02-7?? -02;bbb;<br />;3;03-7?? -02;ccc;<br />;4;04-7?? -02;ddd;<br />;5;05-7?? -02;eee;<br />;6;06-7?? -02;fff;<br /><br />PL/SQL procedure successfully completed.</span>
				</font>
		</p>
<img src ="http://www.cnitblog.com/yide/aggbug/10596.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/yide/" target="_blank">yide</a> 2006-05-16 13:51 <a href="http://www.cnitblog.com/yide/archive/2006/05/16/10596.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>PL/SQL  語句</title><link>http://www.cnitblog.com/yide/archive/2006/05/16/10579.html</link><dc:creator>yide</dc:creator><author>yide</author><pubDate>Tue, 16 May 2006 02:31:00 GMT</pubDate><guid>http://www.cnitblog.com/yide/archive/2006/05/16/10579.html</guid><wfw:comment>http://www.cnitblog.com/yide/comments/10579.html</wfw:comment><comments>http://www.cnitblog.com/yide/archive/2006/05/16/10579.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/yide/comments/commentRss/10579.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/yide/services/trackbacks/10579.html</trackback:ping><description><![CDATA[pl/sql 是结构化程序设计语言，块(block)是pl/sql 程序中最基本的结构，所有的pl/sql程序都是由块组成的。<br />pl/sql 由变量说明，程序代码，和异常处理代码3部分组成。<br /><br />declare -----标记声明部分<br /> begin ------标记程序体部分开始<br />exception ------标记异常处理部分开始<br />end;       --------标记程序体部分结束<br /><br /> <br /><br />pl/sql 示例<br /><br /><br />1&gt;    <br /><br />    set serveroutput on;<br />    declare <br />   empname varchar2(20);<br />   begin <br />        select emp_name into empname from cus_emp_basic where emp_no='00000027';<br />        dbms_output.put_line(empname);<br />    end ;<br /><br /><br />使用set serveroutput on 命令设置环境变量serveroutput为打开状态，从而使得pl/sql程序能够再SQL*plus和SQL*plus中输出结果<br /><br />使用函数dbms_output.put_line()可以输出参数的值。<br /><br />1&gt;条件语句<br /><br />      set serveroutput on ;<br />declare <br />     num integer :=3;<br />     begin <br />         if num&lt; 0 then<br />          dbms_output.put_line('负数');<br />         elsif num &gt; 0 then<br />          dbms_output.put_line('正数');<br />         else<br />          dbms_output.put_line('0');<br />         end if;<br />     end;<br /><br /> <br /><br />2&gt;<br /><br />循环语句loop ......exit....end<br /><br />     set serveroutput on;<br />declare<br />    num integer:=1;<br />    v_sum integer:=0;<br />begin<br />   loop<br />      v_sum:=v_sum+num;<br />      dbms_output.put_line(num);<br />      if num=4 then<br />      exit;<br />      end if;<br />      <br />      dbms_output.put_line('+');      <br />      num:=num+1;<br />   end loop;<br />   <br />      dbms_output.put_line('=');<br />      dbms_output.put_line(v_sum);<br /> end;<br /><br /><br />3&gt;<br />循环语句 loop......exit when ...end <br /><br /> set serveroutput on;<br />  declare <br />   v_num integer:=1;<br />    v_sum integer:=0;<br />begin <br />     <br />     loop<br />        v_sum:=v_sum+v_num;<br />        dbms_output.put_line(v_num);<br />        exit when v_num=4;<br />        <br />        dbms_output.put_line('+');<br />        v_num:=v_num+1;<br />     end loop;<br />     <br />  dbms_output.put_line('=');<br />  dbms_output.put_line(v_sum);<br />  end;<br /><br />4&gt; <br /><br />循环语句 while...loop...end loop<br /><br /><br />  set serveroutput on ;<br />declare<br />    <br />     v_num integer:=1;<br />     v_sum integer:=0;<br /><br />begin<br />   <br />    while v_num &lt;=4 <br />    loop <br />       v_sum:=v_sum+v_num;<br />       dbms_output.put_line(v_num);<br />       if v_num &lt;4 then<br />       dbms_output.put_line('+');<br />       end if;<br />      <br />       v_num:=v_num+1;<br />       end loop;<br />       dbms_output.put_line('=');<br />       dbms_output.put_line(v_sum);<br /> end;<br /><br /> <br /><br />5&gt;<br /><br />循环语句for...in..loop....end loop <br /><br /> <br /><br /><br />set serveroutput on;<br />declare<br />     v_num integer;<br />     v_sum integer:=0;<br /> begin<br />     <br />      for v_num in 1..4<br />      loop<br />         v_sum:=v_sum+v_num;<br />         dbms_output.put_line(v_num);<br />          if v_num&lt; 4 then<br />             dbms_output.put_line('+');<br />          end if;<br />          end loop;<br />          <br />          dbms_output.put_line('=');<br />          dbms_output.put_line(v_sum);<br />          end;<br /><img src ="http://www.cnitblog.com/yide/aggbug/10579.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/yide/" target="_blank">yide</a> 2006-05-16 10:31 <a href="http://www.cnitblog.com/yide/archive/2006/05/16/10579.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>sql/plus command</title><link>http://www.cnitblog.com/yide/archive/2006/05/16/10577.html</link><dc:creator>yide</dc:creator><author>yide</author><pubDate>Tue, 16 May 2006 02:01:00 GMT</pubDate><guid>http://www.cnitblog.com/yide/archive/2006/05/16/10577.html</guid><wfw:comment>http://www.cnitblog.com/yide/comments/10577.html</wfw:comment><comments>http://www.cnitblog.com/yide/archive/2006/05/16/10577.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/yide/comments/commentRss/10577.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/yide/services/trackbacks/10577.html</trackback:ping><description><![CDATA[SQL*PLUS命令的使用大全关键词： ORACLE    SQL*PLUS                                           <br />Oracle的sql*plus是与oracle进行交互的客户端工具。在sql*plus中，可以运行sql*plus命令与sql*plus语句。 <br />   我们通常所说的DML、DDL、DCL语句都是sql*plus语句，它们执行完后，都可以保存在一个被称为sql buffer的内存区域中，并且只能保存一条最近执行的sql语句，我们可以对保存在sql buffer中的sql 语句进行修改，然后再次执行，sql*plus一般都与数据库打交道。 <br />   除了sql*plus语句，在sql*plus中执行的其它语句我们称之为sql*plus命令。它们执行完后，不保存在sql buffer的内存区域中，它们一般用来对输出的结果进行格式化显示，以便于制作报表。 <br />   下面就介绍一下一些常用的sql*plus命令： <br />  <br />1. 执行一个SQL脚本文件 <br />SQL&gt;start file_name <br />SQL&gt;@ file_name <br />我们可以将多条sql语句保存在一个文本文件中，这样当要执行这个文件中的所有的sql语句时，用上面的任一命令即可，这类似于dos中的批处理。 <br />  <br />2. 对当前的输入进行编辑 <br />SQL&gt;edit <br />  <br />3. 重新运行上一次运行的sql语句 <br />SQL&gt;/ <br />  <br />4. 将显示的内容输出到指定文件 <br />SQL&gt; SPOOL file_name <br />   在屏幕上的所有内容都包含在该文件中，包括你输入的sql语句。 <br />  <br />5. 关闭spool输出 <br />SQL&gt; SPOOL OFF <br />   只有关闭spool输出，才会在输出文件中看到输出的内容。 <br />  <br />6．显示一个表的结构 <br />SQL&gt; desc table_name <br />  <br />7. COL命令： <br />主要格式化列的显示形式。 <br />该命令有许多选项，具体如下： <br />COL[UMN] [{ column|expr} [ option ...]] <br />Option选项可以是如下的子句: <br />ALI[AS] alias <br />CLE[AR] <br />FOLD_A[FTER] <br />FOLD_B[EFORE] <br />FOR[MAT] format <br />HEA[DING] text <br />JUS[TIFY] {L[EFT]|C[ENTER]|C[ENTRE]|R[IGHT]} <br />LIKE { expr|alias} <br />NEWL[INE] <br />NEW_V[ALUE] variable <br />NOPRI[NT]|PRI[NT] <br />NUL[L] text <br />OLD_V[ALUE] variable <br />ON|OFF <br />WRA[PPED]|WOR[D_WRAPPED]|TRU[NCATED] <br />  <br />1). 改变缺省的列标题 <br />COLUMN column_name HEADING column_heading <br />For example: <br />Sql&gt;select * from dept; <br />     DEPTNO DNAME                        LOC <br />---------- ---------------------------- --------- <br />         10 ACCOUNTING                   NEW YORK <br />sql&gt;col  LOC heading location <br />sql&gt;select * from dept; <br />    DEPTNO DNAME                        location <br />--------- ---------------------------- ----------- <br />        10 ACCOUNTING                   NEW YORK <br />  <br />2). 将列名ENAME改为新列名EMPLOYEE NAME并将新列名放在两行上： <br />Sql&gt;select * from emp <br />Department  name           Salary <br />---------- ---------- ---------- <br />         10 aaa                11         <br />SQL&gt; COLUMN ENAME HEADING ’Employee|Name’ <br />Sql&gt;select * from emp <br />            Employee <br />Department  name           Salary <br />---------- ---------- ----------  <br />         10 aaa                11 <br />note: the col heading turn into two lines from one line. <br />  <br />3). 改变列的显示长度： <br />FOR[MAT] format <br />Sql&gt;select empno,ename,job from emp; <br />      EMPNO ENAME      JOB        <br />---------- ----------     --------- <br />       7369 SMITH      CLERK      <br />       7499 ALLEN      SALESMAN   <br />7521 WARD       SALESMAN   <br />Sql&gt; col ename format a40 <br />      EMPNO ENAME                                    JOB <br />----------   ----------------------------------------         --------- <br />       7369 SMITH                                    CLERK <br />       7499 ALLEN                                    SALESMAN <br />       7521 WARD                                    SALESMAN <br />  <br />4). 设置列标题的对齐方式 <br />JUS[TIFY] {L[EFT]|C[ENTER]|C[ENTRE]|R[IGHT]} <br />SQL&gt; col ename justify center <br />SQL&gt; / <br />      EMPNO           ENAME                   JOB <br />----------   ----------------------------------------       --------- <br />       7369 SMITH                                    CLERK <br />       7499 ALLEN                                    SALESMAN <br />7521 WARD                                     SALESMAN <br />对于NUMBER型的列，列标题缺省在右边，其它类型的列标题缺省在左边 <br />  <br />5). 不让一个列显示在屏幕上 <br />NOPRI[NT]|PRI[NT] <br />SQL&gt; col job noprint <br />SQL&gt; / <br />      EMPNO           ENAME <br />----------     ---------------------------------------- <br />       7369 SMITH <br />       7499 ALLEN <br />7521 WARD <br />  <br />6). 格式化NUMBER类型列的显示： <br />SQL&gt; COLUMN SAL FORMAT $99,990 <br />SQL&gt; / <br />Employee <br />Department Name        Salary    Commission <br />---------- ---------- --------- ---------- <br />30          ALLEN        $1,600    300 <br />  <br />7). 显示列值时，如果列值为NULL值，用text值代替NULL值 <br />COMM NUL[L] text <br />SQL&gt;COL COMM NUL[L] text <br />  <br />8). 设置一个列的回绕方式 <br />WRA[PPED]|WOR[D_WRAPPED]|TRU[NCATED] <br />        COL1 <br />-------------------- <br />HOW ARE YOU? <br />  <br />SQL&gt;COL COL1 FORMAT A5 <br />SQL&gt;COL COL1 WRAPPED <br />COL1 <br />----- <br />HOW A <br />RE YO <br />U? <br />  <br />SQL&gt; COL COL1 WORD_WRAPPED <br />COL1 <br />----- <br />HOW <br />ARE <br />YOU? <br />  <br />SQL&gt; COL COL1 WORD_WRAPPED <br />COL1 <br />----- <br />HOW A <br />  <br />9). 显示列的当前的显示属性值 <br />SQL&gt; COLUMN column_name <br />  <br />10). 将所有列的显示属性设为缺省值 <br />SQL&gt; CLEAR COLUMNS <br />  <br />8. 屏蔽掉一个列中显示的相同的值 <br />BREAK ON break_column <br />SQL&gt; BREAK ON DEPTNO <br />SQL&gt; SELECT DEPTNO, ENAME, SAL <br />FROM EMP <br />  WHERE SAL &lt; 2500 <br />  ORDER BY DEPTNO; <br />DEPTNO      ENAME         SAL <br />---------- ----------- --------- <br />10           CLARK        2450 <br />MILLER      1300 <br />20            SMITH       800 <br />ADAMS       1100 <br />  <br />9. 在上面屏蔽掉一个列中显示的相同的值的显示中，每当列值变化时在值变化之前插入n个空行。 <br />BREAK ON break_column SKIP n <br />  <br />SQL&gt; BREAK ON DEPTNO SKIP 1 <br />SQL&gt; / <br />DEPTNO ENAME SAL <br />---------- ----------- --------- <br />10 CLARK 2450 <br />MILLER 1300 <br />  <br />20 SMITH 800 <br />ADAMS 1100 <br />  <br />10. 显示对BREAK的设置 <br />SQL&gt; BREAK <br />  <br />11. 删除6、7的设置 <br />SQL&gt; CLEAR BREAKS <br />  <br />12. Set 命令： <br />该命令包含许多子命令： <br />SET system_variable value <br />system_variable value 可以是如下的子句之一： <br />APPI[NFO]{ON|OFF|text} <br />ARRAY[SIZE] {15|n} <br />AUTO[COMMIT]{ON|OFF|IMM[EDIATE]|n} <br />AUTOP[RINT] {ON|OFF} <br />AUTORECOVERY [ON|OFF] <br />AUTOT[RACE] {ON|OFF|TRACE[ONLY]} [EXP[LAIN]] [STAT[ISTICS]] <br />BLO[CKTERMINATOR] {.|c} <br />CMDS[EP] {;|c|ON|OFF} <br />COLSEP {_|text} <br />COM[PATIBILITY]{V7|V8|NATIVE} <br />CON[CAT] {.|c|ON|OFF} <br />COPYC[OMMIT] {0|n} <br />COPYTYPECHECK {ON|OFF} <br />DEF[INE] {&amp;|c|ON|OFF} <br />DESCRIBE [DEPTH {1|n|ALL}][LINENUM {ON|OFF}][INDENT {ON|OFF}] <br />ECHO {ON|OFF} <br />EDITF[ILE] file_name[.ext] <br />EMB[EDDED] {ON|OFF} <br />ESC[APE] {\|c|ON|OFF} <br />FEED[BACK] {6|n|ON|OFF} <br />FLAGGER {OFF|ENTRY |INTERMED[IATE]|FULL} <br />FLU[SH] {ON|OFF} <br />HEA[DING] {ON|OFF} <br />HEADS[EP] {||c|ON|OFF} <br />INSTANCE [instance_path|LOCAL] <br />LIN[ESIZE] {80|n} <br />LOBOF[FSET] {n|1} <br />LOGSOURCE [pathname] <br />LONG {80|n} <br />LONGC[HUNKSIZE] {80|n} <br />MARK[UP] HTML [ON|OFF] [HEAD text] [BODY text] [ENTMAP {ON|OFF}] [SPOOL <br />{ON|OFF}] [PRE[FORMAT] {ON|OFF}] <br />NEWP[AGE] {1|n|NONE} <br />NULL text <br />NUMF[ORMAT] format <br />NUM[WIDTH] {10|n} <br />PAGES[IZE] {24|n} <br />PAU[SE] {ON|OFF|text} <br />RECSEP {WR[APPED]|EA[CH]|OFF} <br />RECSEPCHAR {_|c} <br />SERVEROUT[PUT] {ON|OFF} [SIZE n] [FOR[MAT] {WRA[PPED]|WOR[D_ <br />WRAPPED]|TRU[NCATED]}] <br />SHIFT[INOUT] {VIS[IBLE]|INV[ISIBLE]} <br />SHOW[MODE] {ON|OFF} <br />SQLBL[ANKLINES] {ON|OFF} <br />SQLC[ASE] {MIX[ED]|LO[WER]|UP[PER]} <br />SQLCO[NTINUE] {&gt; |text} <br />SQLN[UMBER] {ON|OFF} <br />SQLPRE[FIX] {#|c} <br />SQLP[ROMPT] {SQL&gt;|text} <br />SQLT[ERMINATOR] {;|c|ON|OFF} <br />SUF[FIX] {SQL|text} <br />TAB {ON|OFF} <br />TERM[OUT] {ON|OFF} <br />TI[ME] {ON|OFF} <br />TIMI[NG] {ON|OFF} <br />TRIM[OUT] {ON|OFF} <br />TRIMS[POOL] {ON|OFF} <br />UND[ERLINE] {-|c|ON|OFF} <br />VER[IFY] {ON|OFF} <br />WRA[P] {ON|OFF} <br />  <br />1). 设置当前session是否对修改的数据进行自动提交 <br />SQL&gt;SET AUTO[COMMIT] {ON|OFF|IMM[EDIATE]| n} <br />  <br />2)．在用start命令执行一个sql脚本时，是否显示脚本中正在执行的SQL语句 <br />SQL&gt; SET ECHO {ON|OFF} <br />  <br />3).是否显示当前sql语句查询或修改的行数 <br />SQL&gt; SET FEED[BACK] {6|n|ON|OFF} <br />   默认只有结果大于6行时才显示结果的行数。如果set feedback 1 ，则不管查询到多少行都返回。当为off 时，一律不显示查询的行数 <br />  <br />4).是否显示列标题 <br />SQL&gt; SET HEA[DING] {ON|OFF} <br />当set heading off 时，在每页的上面不显示列标题，而是以空白行代替 <br />  <br />5).设置一行可以容纳的字符数 <br />SQL&gt; SET LIN[ESIZE] {80|n} <br />   如果一行的输出内容大于设置的一行可容纳的字符数，则折行显示。 <br />  <br />6).设置页与页之间的分隔 <br />SQL&gt; SET NEWP[AGE] {1|n|NONE} <br />当set newpage 0 时，会在每页的开头有一个小的黑方框。 <br />当set newpage n 时，会在页和页之间隔着n个空行。 <br />当set newpage none 时，会在页和页之间没有任何间隔。 <br />  <br />7).显示时，用text值代替NULL值 <br />SQL&gt; SET NULL text <br />  <br />8).设置一页有多少行数 <br />SQL&gt; SET PAGES[IZE] {24|n} <br />如果设为0，则所有的输出内容为一页并且不显示列标题 <br />  <br />9).是否显示用DBMS_OUTPUT.PUT_LINE包进行输出的信息。 <br />SQL&gt; SET SERVEROUT[PUT] {ON|OFF}  <br />在编写存储过程时，我们有时会用dbms_output.put_line将必要的信息输出，以便对存储过程进行调试，只有将serveroutput变量设为on后，信息才能显示在屏幕上。 <br />  <br />10).当SQL语句的长度大于LINESIZE时，是否在显示时截取SQL语句。 <br />SQL&gt; SET WRA[P] {ON|OFF} <br />   当输出的行的长度大于设置的行的长度时（用set linesize n命令设置），当set wrap on时，输出行的多于的字符会另起一行显示，否则，会将输出行的多于字符切除，不予显示。 <br />  <br />11).是否在屏幕上显示输出的内容，主要用与SPOOL结合使用。 <br />SQL&gt; SET TERM[OUT] {ON|OFF} <br />   在用spool命令将一个大表中的内容输出到一个文件中时，将内容输出在屏幕上会耗费大量的时间，设置set termspool off后，则输出的内容只会保存在输出文件中，不会显示在屏幕上，极大的提高了spool的速度。 <br />  <br />12).将SPOOL输出中每行后面多余的空格去掉 <br />SQL&gt; SET TRIMS[OUT] {ON|OFF}  <br />    <br />13)显示每个sql语句花费的执行时间 <br />set TIMING  {ON|OFF} <br />  <br />14．修改sql buffer中的当前行中，第一个出现的字符串 <br />C[HANGE] /old_value/new_<br /> <br />□阅读全文(33) | 回复(0) | 引用通告(0) | 编辑  <br /><img src ="http://www.cnitblog.com/yide/aggbug/10577.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/yide/" target="_blank">yide</a> 2006-05-16 10:01 <a href="http://www.cnitblog.com/yide/archive/2006/05/16/10577.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>FW : ORACLE锁的管理</title><link>http://www.cnitblog.com/yide/archive/2006/02/22/6844.html</link><dc:creator>yide</dc:creator><author>yide</author><pubDate>Wed, 22 Feb 2006 08:34:00 GMT</pubDate><guid>http://www.cnitblog.com/yide/archive/2006/02/22/6844.html</guid><wfw:comment>http://www.cnitblog.com/yide/comments/6844.html</wfw:comment><comments>http://www.cnitblog.com/yide/archive/2006/02/22/6844.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/yide/comments/commentRss/6844.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/yide/services/trackbacks/6844.html</trackback:ping><description><![CDATA[<P>ORACLE里锁有以下几种模式:&nbsp; <BR><BR>0：none&nbsp; <BR>1：null&nbsp;空&nbsp; <BR>2：Row-S&nbsp;行共享(RS)：共享表锁，sub&nbsp;share&nbsp; <BR>3：Row-X&nbsp;行独占(RX)：用于行的修改，sub&nbsp;exclusive&nbsp; <BR>4：Share&nbsp;共享锁(S)：阻止其他DML操作，share&nbsp; <BR>5：S/Row-X&nbsp;共享行独占(SRX)：阻止其他事务操作，share/sub&nbsp;exclusive&nbsp; <BR>6：exclusive&nbsp;独占(X)：独立访问使用，exclusive&nbsp; <BR><BR>数字越大锁级别越高,&nbsp;影响的操作越多。<BR><BR><STRONG>1级锁</STRONG>有：Select，有时会在v$locked_object出现。 <BR><STRONG>2级锁</STRONG>有：Select&nbsp;for&nbsp;update,Lock&nbsp;For&nbsp;Update,Lock&nbsp;Row&nbsp;Share&nbsp; <BR>select&nbsp;for&nbsp;update当对话使用for&nbsp;update子串打开一个游标时，所有返回集中的数据行都将处于行级(Row-X)独占式锁定，其他对象只能查询这些数据行，不能进行update、delete或select&nbsp;for&nbsp;update操作。 <BR><STRONG>3级锁</STRONG>有：Insert,&nbsp;Update,&nbsp;Delete,&nbsp;Lock&nbsp;Row&nbsp;Exclusive <BR>没有commit之前插入同样的一条记录会没有反应,&nbsp;因为后一个3的锁会一直等待上一个3的锁,&nbsp;我们必须释放掉上一个才能继续工作。 <BR><STRONG>4级锁</STRONG>有：Create&nbsp;Index,&nbsp;Lock&nbsp;Share <BR>locked_mode为2,3,4不影响DML(insert,delete,update,select)操作,&nbsp;但DDL(alter,drop等)操作会提示ora-00054错误。 <BR>00054,&nbsp;00000,&nbsp;"resource&nbsp;busy&nbsp;and&nbsp;acquire&nbsp;with&nbsp;NOWAIT&nbsp;specified" <BR>//&nbsp;*Cause:&nbsp;Resource&nbsp;interested&nbsp;is&nbsp;busy. <BR>//&nbsp;*Action:&nbsp;Retry&nbsp;if&nbsp;necessary. <BR><STRONG>5级锁</STRONG>有：Lock&nbsp;Share&nbsp;Row&nbsp;Exclusive&nbsp; <BR>具体来讲有主外键约束时update&nbsp;/&nbsp;delete&nbsp;...&nbsp;;&nbsp;可能会产生4,5的锁。 <BR><STRONG>6级锁</STRONG>有：Alter&nbsp;table,&nbsp;Drop&nbsp;table,&nbsp;Drop&nbsp;Index,&nbsp;Truncate&nbsp;table,&nbsp;Lock&nbsp;Exclusive <BR><BR>以DBA角色,&nbsp;查看当前数据库里锁的情况可以用如下SQL语句： <BR><BR>col&nbsp;owner&nbsp;for&nbsp;a12 <BR>col&nbsp;object_name&nbsp;for&nbsp;a16 <BR>select&nbsp;b.owner,b.object_name,l.session_id,l.locked_mode <BR>from&nbsp;v$locked_object&nbsp;l,&nbsp;dba_objects&nbsp;b <BR>where&nbsp;b.object_id=l.object_id <BR>/ <BR><BR>select&nbsp;t2.username,t2.sid,t2.serial#,t2.logon_time&nbsp; <BR>from&nbsp;v$locked_object&nbsp;t1,v$session&nbsp;t2&nbsp; <BR>where&nbsp;t1.session_id=t2.sid&nbsp;order&nbsp;by&nbsp;t2.logon_time <BR>/ <BR><BR>如果有长期出现的一列，可能是没有释放的锁。我们可以用下面SQL语句杀掉长期没有释放非正常的锁： <BR><BR>alter&nbsp;system&nbsp;kill&nbsp;session&nbsp;'sid,serial#'; <BR><BR>如果出现了锁的问题,&nbsp;某个DML操作可能等待很久没有反应。 <BR><BR>当你采用的是直接连接数据库的方式，也不要用OS系统命令&nbsp;$kill&nbsp;process_num&nbsp;<BR>或者&nbsp;$kill&nbsp;-9&nbsp;process_num来终止用户连接，因为一个用户进程可能产生一个以上的锁,&nbsp;杀OS进程并不能彻底清除锁的问题。</P>
<P>
<TABLE border=1>
<TBODY>
<TR>
<TD>
<TABLE style="WORD-BREAK: break-all; BORDER-COLLAPSE: collapse" cellSpacing=0 cellPadding=0 width="90%" align=center border=0>
<TBODY>
<TR>
<TD><SMALL><A href="http://www.chinaunix.net/forum/profile.php?mode=viewprofile&amp;u=26127" target=_blank><FONT color=#4a664d size=1>crazybaw</FONT></A><FONT size=1> 回复于：2003-09-22 19:09:57</FONT></SMALL></TD></TR>
<TR>
<TD>这种操作只适合有用户会话的，假设在USERNAME字段中是空的呢，这样做的时候ORACLE会报错，提示“会话不是用户会话”，请问该如何处理 <BR>操作和结果如下： <BR><BR>select&nbsp;t2.username,t2.sid,t2.serial#,t2.logon_time&nbsp; <BR>from&nbsp;v$locked_object&nbsp;t1,v$session&nbsp;t2&nbsp; <BR>where&nbsp;t1.session_id=t2.sid&nbsp;order&nbsp;by&nbsp;t2.logon_time&nbsp; <BR>结果： <BR>username为空&nbsp;，sid为5，&nbsp;serial#为1，&nbsp;logon_time为一3天前的时间 <BR>，然后执行alter&nbsp;system&nbsp;kill&nbsp;session&nbsp;'5,1#';&nbsp;ORACLE报错，提示“会话不是用户会话”，无法删除。<BR><BR></TD></TR>
<TR>
<TD>
<HR>
<SMALL><FONT size=1>&nbsp;</FONT><A href="http://www.chinaunix.net/forum/profile.php?mode=viewprofile&amp;u=26127" target=_blank><FONT color=#4a664d size=1>crazybaw</FONT></A><FONT size=1> 回复于：2003-09-22 19:16:46</FONT></SMALL></TD></TR>
<TR>
<TD>请问我执行查询：select&nbsp;b.owner,b.object_name,l.session_id,l.locked_mode&nbsp; <BR>from&nbsp;v$locked_object&nbsp;l,&nbsp;dba_objects&nbsp;b&nbsp; <BR>where&nbsp;b.object_id=l.object_id&nbsp; <BR>得到的结果如下： <BR>owner=SYS，OBJECT_NAME=FET$,SESSION_ID,LOCKED_MODE=3，请问该如何处理？字段OBJECT_NAME=FET$和LOCKED_MODE=3表示什么？LOCKED_MODE=3是否表示Row-X&nbsp;行独占(RX)：用于行的修改，sub&nbsp;exclusive？<BR><BR></TD></TR>
<TR>
<TD>
<HR>
<SMALL><FONT size=1>&nbsp;</FONT><A href="http://www.chinaunix.net/forum/profile.php?mode=viewprofile&amp;u=31634" target=_blank><FONT color=#4a664d size=1>rollingpig</FONT></A><FONT size=1> 回复于：2003-09-23 08:54:49</FONT></SMALL></TD></TR>
<TR>
<TD>alter&nbsp;system&nbsp;kill&nbsp;session&nbsp;'5,1';<BR><BR></TD></TR>
<TR>
<TD>
<HR>
<SMALL><FONT size=1>&nbsp;</FONT><A href="http://www.chinaunix.net/forum/profile.php?mode=viewprofile&amp;u=61206" target=_blank><FONT color=#4a664d size=1>wxx</FONT></A><FONT size=1> 回复于：2003-09-23 10:41:35</FONT></SMALL></TD></TR>
<TR>
<TD>这种问题在Oracle8i中会比较常遇到，特别是在本地网计费项目中，因为当时Oracle狂推OPS，但是许多集成商的OPS的使用能力实在有限，所以常常会因为OPS导致许多问题，特别是在销账高峰期常常会出问题：数据库被挂死，一个节点的Instance出问题，另外一个也就被挂死了。&nbsp;这些问题的解决关键要设置好OPS的相关参数，以及相关库表的存储参数才能解决问题，而且在销账高峰期要尽量避免想其他的大事务操作，否则因为都要操作数据字典也会带来一些问题。<BR><BR></TD></TR>
<TR>
<TD>
<HR>
<SMALL><FONT size=1>&nbsp;</FONT><A href="http://www.chinaunix.net/forum/profile.php?mode=viewprofile&amp;u=26127" target=_blank><FONT color=#4a664d size=1>crazybaw</FONT></A><FONT size=1> 回复于：2003-09-23 11:24:02</FONT></SMALL></TD></TR>
<TR>
<TD>[quote:1a0cf9cf18="rollingpig"]alter&nbsp;system&nbsp;kill&nbsp;session&nbsp;'5,1';[/quote:1a0cf9cf18]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR><BR>呵呵，我用的就是alter&nbsp;system&nbsp;kill&nbsp;session&nbsp;'5,1'，只不过在上面的帖子手误而已。<BR><BR></TD></TR>
<TR>
<TD>
<HR>
<SMALL><FONT size=1>&nbsp;</FONT><A href="http://www.chinaunix.net/forum/profile.php?mode=viewprofile&amp;u=26127" target=_blank><FONT color=#4a664d size=1>crazybaw</FONT></A><FONT size=1> 回复于：2003-09-23 11:30:38</FONT></SMALL></TD></TR>
<TR>
<TD>[quote:da7fe0de27="wxx"]这种问题在Oracle8i中会比较常遇到，特别是在本地网计费项目中，因为当时Oracle狂推OPS，但是许多集成商的OPS的使用能力实在有限，所以常常会因为OPS导致许多问题，特别是在销账高峰期常常会出问题：数据库被挂死，?.........[/quote:da7fe0de27]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR><BR>出现该情况的条件很多，电信上面的确暴露的比较明显<BR><BR></TD></TR>
<TR>
<TD>
<HR>
<SMALL><FONT size=1>&nbsp;</FONT><A href="http://www.chinaunix.net/forum/profile.php?mode=viewprofile&amp;u=31634" target=_blank><FONT color=#4a664d size=1>rollingpig</FONT></A><FONT size=1> 回复于：2003-09-23 11:30:58</FONT></SMALL></TD></TR>
<TR>
<TD>呵呵 <BR>那就郁闷了<BR><BR></TD></TR>
<TR>
<TD>
<HR>
<SMALL><FONT size=1>&nbsp;</FONT><A href="http://www.chinaunix.net/forum/profile.php?mode=viewprofile&amp;u=48568" target=_blank><FONT color=#4a664d size=1>peterking</FONT></A><FONT size=1> 回复于：2003-09-23 11:48:20</FONT></SMALL></TD></TR>
<TR>
<TD>交易通过CICS调用ORACLE的，一般不应该直接kill&nbsp;session。应该找出session&nbsp;对应的process&nbsp;id，在操作系统中kill&nbsp;-9&nbsp;pid，锁可以自动释放。<BR><BR></TD></TR>
<TR>
<TD>
<HR>
<SMALL><FONT size=1>&nbsp;</FONT><A href="http://www.chinaunix.net/forum/profile.php?mode=viewprofile&amp;u=84104" target=_blank><FONT color=#4a664d size=1>zhaoyang</FONT></A><FONT size=1> 回复于：2003-09-26 21:50:15</FONT></SMALL></TD></TR>
<TR>
<TD><FONT size=1><BR><BR></FONT></TD></TR>
<TR>
<TD><FONT size=1>
<HR>
<SMALL>&nbsp;<A href="http://www.chinaunix.net/forum/profile.php?mode=viewprofile&amp;u=9757" target=_blank><FONT color=#4a664d>flysnowpp</FONT></A> 回复于：2003-09-27 09:36:23</SMALL></FONT></TD></TR>
<TR>
<TD>用9i的RAC就好多了，锁的问题解决了不少。 <BR>[quote:5e5ba27208="wxx"]这种问题在Oracle8i中会比较常遇到，特别是在本地网计费项目中，因为当时Oracle狂推OPS，但是许多集成商的OPS的使用能力实在有限，所以常常会因为OPS导致许多问题，特别是在销账高峰期常常会出问题：数据库被挂死，?.........[/quote:5e5ba27208]<BR></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE></P>
<P>转自<A href="http://www.dbonline.cn/source/oracle/20031217/BACKUP_unsafe%20factor%20and%20illuminate%20of%20oracle8i.html"><FONT color=#4a664d>http://www.dbonline.cn/source/oracle/20031217/BACKUP_unsafe%20factor%20and%20illuminate%20of%20oracle8i.html</FONT></A></P>
<P>作为对象关系型数据库的杰出代表，Oracle无疑是最具实力的。无论是在数据库的规模，多媒体数据类型的支持，SQL操作复制的并行性还是在安全服务方面，Oracle均比SYBASE、Informix强许多，加上其最新版本Oracle8.0.4更是增强了这方面的特性，而且还引入了一些新的特性，比如：数据分区(Data Partitioning)、对象关系技术(Object Relational Technology)、唯索引表(Index only tables)、连接管理器(Connection Manager)[NET8特性]、高级队列(Advanced Quening)等，所以有一种说法：Oracle8是适用于如Peoplesoft，SAP和Baan等封装式应用系统最好的数据库引擎。 </P>
<P>　　虽然Oracle8有许多的优点，但正如微软的WINDOWS系统也会死机一样，任何再好的软件也有他的缺陷，一个优秀的软件不可能就是十全十美，他只是避免了大多数常见的或者可能被考虑到的问题，而一些不容易被发现却非常致命的问题往往会被疏忽掉。Oracle8也同样存在着不安全的因素，许多正在想尽快升级到Oracle8的Oracle7.1、Oracle7.2、Oracle7.3用户不能不考虑到这个因素。当然，这个不安全因素并不是一下子就发现的，而是我们在对一个非常庞大的表进行管理时发现的，这种隐患在使用Oracle创建的小型或者中型数据库中可能不会出现或根本无法发现，因为Oracle8独有的特性已经将这种隐患降低到最低的程度，你大可放心你的数据库系统的安全。 
<P>
<H2 class=style35>问题 </H2>
<P>　　我们安装的Oracle8数据库是工作于主机-终端方式下的，系统主机采用的是四台HP-9000小型机、1.5G的内存。建库初期时设定的最大事务数是按Oracle8的默认取值[这也是Oracle7的默认取值]取的：块值为2K，事务数为32（对于一个要处理非常庞大的数据库时，一般我们设定的块值要大于2K，至少应为4K或者16K，当然这还与主机的CPU能力和I/0能力值有关），并在建库时没有进行分区建表，这也许就为以后数据库出问题留下了隐患。由于日访问数据库的用户非常多，而且对同一表操作的用户数量太大，致使那个表经常被锁住，不断有用户抱怨他们进不了系统，主机发送的数据包太慢，经常报ORA-600的错误。起初我们以为是系统网络问题，但这种可能性比较小，因为我们发现系统CPU峰值经常在90%多，空闲很小，数据库资源太忙，同时有十多个人锁住一个大表进行操作，自然一部分用户就无法进入系统，对此我们写了如下的SQL语句对锁表用户进行监控： 
<P>SELECT OBJECT_ID,SESSION_ID,SERIAL#, <BR>ORACLE_USERNAME,OS_USER_NAME,S.PROCESS <BR>FROM V$LOCKED_OBJECT A, <BR>V$SESSION S WHERE A.SESSION_ID=S.SID; <BR>
<P>也许有的人会问为什么不用如下的SQL语句进行查询： 
<P>SELECT a.username,a.sid,a.serial#,b.id1, <BR>c.sql_text from v$session a, <BR>V$lock b,v$sqltext c where a.lockwait=b.kaddr and <BR>a. sql_address=c.address and a.sql_hash_value=c.hash_value; <BR>
<P>　　以上两个SQL语句都会查询返回当前被锁住的用户列表，但第二个SQL语句由于加入了sql_text从而使这个查询变得非常的慢长，特别是在有许多用户同时对数据库进行操作时，建议不用，第一个SQL 语句会在很短的时间内查询出是谁在锁表，从而有利于对数据库的管理，一但有用户进入不了，我们就马上杀死其锁进程[SID，SERIAL#]，SQL语句如下：ALTER SYSTEM KILL SESSION ‘SID，SERIAL#'，但这并不是解决问题的根本方法，只能暂时缓解一下；另外我们还发现回滚段时常有“online”与“offline”的现象，于是我们又考虑是否是回滚段引起的问题：因为我们一但对大的回滚段进行操作，马上就会有用户反映无法进入。我们知道回退段的大小直接依赖于数据库的活动状态，而每一个EXTENTS都应具有相同的值（Oracle的推荐）[INITIAL EXTENTS的值可以从2K（32）、4K（69）、8K（142）、16K、32K等列表中选择]，这将保证你删掉一个区的时候，你可以重新使用它的空间而不会造成浪费，另外MINEXTENTS应设为20，这将不会使回退段扩展另一个EXTENT时用到正在被活动的事务所使用的空间，因而我们就可以据此来确定回退段大小，查出数据库正常运行时所需回滚段的尺寸,为此我们重新设置了回退段的OPTIMAL参数[事实是OPTIMAL的值并不足引起数据库出错]，增大了OPTIMAL的值，使用命令SET TRANSACTION USE ROLLBACK SEGMENT为系统指定了一个大的回退段[注意OPTIMAL参数要足够大以使ORACLE不需经常回缩和重新分配EXTENTS，如果设得小于最小覆盖值，性能将由于额外的段重设置而下降，对于一个要执行长查询的系统，OPTIMAL应设成足够大以避免ORA-1555，“Smapshot too old”的错误，而对于运行小的事务，OPTIMAL应设得小一些，使回退段足够小以便放于内存中，这将提高系统性能。]，但我们发现这样做后，ORA-600的错误依然出现，而且锁表越来越严重；我们又考虑暂时锁住这个表，不让用户进入，先把用户的锁进程全部杀完再看，由于一开始就采用了主机-终端的工作方式，因而根本就无法清除得完，除非断掉外部的所有网络连接，但那样无疑是重启数据库，最终我们选择了重启数据库。 
<P>　　重启数据库后系统资源一下子得以释放，用户明显感觉速度上来了，能够保证正常使用，就在我们认为系统可能是因为长期没有DOWN机，用户登录数过多造成数据库死锁的时候，一个非常严重的问题出现了，那个表中的一个数据无法进行UPDATE，一UPDATE就报ORACLE内部代码错误，当时我们并没在意，但是不久，我们又发现另一表中编号有重复的现象，根据ORACLE8的数据唯索引表性，这种现象应该根本不会存在，因为我们在这个表中只建立了唯一索引，于是我们电话询问ORACLE公司的技术工程师，也许ORACLE的技术工程师们也是第一次遇到这种问题，他们的回答是数据字典太老，数据索引坏掉，建议重建索引，并把问题向亚太反映。在ORACLE公司的技术工程师的指导下，我们重建了该表，并重新建立了索引，在重建索引过程中，开始几次都不成功，而且无法DROP掉先前的表，经过仔细的查找，我们发现ORACLE8中的确有索引重复的现象，一个表中有两条重复的索引，直接导致数据库HANG，不能访问，但查看系统状态、进程、LISTENER却都正常，从日志文件来看，文件过小（7MB），CHECK POINT频繁，影响到了系统的性能，通过以上调整后，数据库问题暂时缓解了，可以做UPDATE，但是ORACLE的内部代码错误却依然存在，只是暂时还不会影响到我们对数据库的使用，而回滚段开始出现“online rollback segment”的问题，更加令人不解的是数据库居然出现了自动DOWN机的现象，于是我们再次询问ORACLE公司的技术工程师，他们的答复是ORACLE已经注意到了ORACLE8.0.4版本的一些问题，他们将会给数据库打PATCH，希望能够解决到这些问题，但是考虑到给数据库打一个PATCH，将会把所有的数据都要EXPORT出来，这将是一个非常危险的操作，而且所有主机上的程序都要重新编译一到，没有一个星期的时间是无法做好的，而那是根本不可能的事情，因而我们现在还在等待ORACLE公司一个更好的解决办法。 
<P>
<H2 class=style35>说明 </H2>
<P>　　以上问题可能是ORACLE的一个BUG，但任何软件都有它不完善的一面，否则又何必出什么补丁了，有了补丁肯定会比没有补丁强，但是我们在设计一个系统时也一定要考虑到以下的一些方面： 
<P>　　1、 主机系统的CPU能力与I/0能力：HP偏重于I/0能力，CPU能力不强，你的数据库就应该尽量避免让CPU占用率太大；DEC偏重于CPU能力，I/0能力不强，你的数据库就可以考虑适当增大某些占用CPU参数的设置；SUN的CPU能力与I/0能力差不多，你的数据库就应该考虑平衡参数，过大过小都不好。 
<P>　　2、 增大日志文件的SIZE，至少不会低于8MB，日志文件过小会导致CHECK POINT频繁，从而影响到系统的性能。 
<P>　　3、 回滚段最好保持一个比较合理的值，对一些较大的回滚段可适当增加MINEXTENTS，并设置OPTIMAL，保证一般事物处理无需经常动态分配空间与及时回收空间。 
<P>　　4、 要充分利用CPU系统资源及提高CPU的命中率，可适当增大log_simultaneous_copies,db_block_latches,db_writes的设置。 
<P>　　5、 适当增加db_block_buffera与share_pool_size的SIZE，以提高BUFFER值，增加内存，尽快提高BUFF及SQL的命中率。 
<P>　　6、 主机-终端方式尽管可以便于数据维持，但主机-终端方式却造成主机负荷太重，建议采用客户-服务端方式建系统。<BR><BR></P>
<DIV class=diaryTitleBg>怎样快速查出Oracle 数据库中的锁等待 </DIV>
<DIV class=diaryTime>时间: 2004-05-31 </DIV>
<DIV class=diaryBody>
<DIV align=center>摘自《计算机世界日报》(文/赵华良)</DIV>
<P>----&nbsp;在大型数据库系统中，为了保证数据的一致性，在对数据库中的数据进行操作时，系统会进行对数据相应的锁定。&nbsp;<BR><BR>----&nbsp;这些锁定中有"只读锁"、"排它锁"，"共享排它锁"等多种类型，而且每种类型又有"<STRONG>行级锁</STRONG>"（一次锁住一条记录），"<STRONG>页级锁</STRONG>"（一次锁住一页，即数据库中存储记录的最小可分配单元），"<STRONG>表级锁</STRONG>"（锁住整个表）。&nbsp;<BR><BR>----&nbsp;若为"<STRONG>行级排它锁</STRONG>"，则除被锁住的该行外，该表中其它行均可被其它的用户进行修改(Update)或删除(delete)操作，若为"<STRONG>表级排它锁</STRONG>"，则所有其它用户只能对该表进行查询(select)操作，而无法对其中的任何记录进行修改或删除。当程序对所做的修改进行提交(commit)或回滚后(rollback)后，锁住的资源便会得到释放，从而允许其它用户进行操作。&nbsp;<BR><BR>----&nbsp;但是，有时，由于程序中的原因，锁住资源后长时间未对其工作进行提交；或是由于用户的原因，如调出需要修改的数据后，未及时修改并提交，而是放置于一旁；或是由于客户服务器方式中客户端出现"死机"，而服务器端却并未检测到，从而造成锁定的资源未被及时释放，影响到其它用户的操作。&nbsp;<BR><BR>----&nbsp;因而，如何迅速地诊断出锁住资源的用户以及解决其锁定便是数据库管理员的一个挑战。&nbsp;<BR><BR>----&nbsp;由于数据库应用系统越来越复杂，&nbsp;一旦出现由于锁资源未及时释放的情况，便会引起对一相同表进行操作的大量用户无法进行操作，从而影响到系统的使用。此时，DBA应尽量快地解决问题。但是，由于在Oracle&nbsp;8.0.x&nbsp;中执行"获取正在等待锁资源的用户名"的查询语句&nbsp;<BR><BR>select&nbsp;a.username,&nbsp;a.sid,&nbsp;a.serial#,&nbsp;b.id1<BR>&nbsp;&nbsp;from&nbsp;v$session&nbsp;a,&nbsp;v$lock&nbsp;b<BR>&nbsp;&nbsp;where&nbsp;a.lockwait&nbsp;=&nbsp;b.kaddr<BR><BR>----&nbsp;十分缓慢，（在&nbsp;Oracle&nbsp;7.3.4中执行很快)，而且，执行"查找阻塞其它用户的用户进程"的查询语句&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;select&nbsp;a.username,&nbsp;a.sid,&nbsp;a.serial#,&nbsp;b.id1<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;from&nbsp;v$session&nbsp;a,&nbsp;v$lock&nbsp;b<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;where&nbsp;b.id1&nbsp;in<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(select&nbsp;distinct&nbsp;e.id1<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;from&nbsp;v$session&nbsp;d,&nbsp;v$lock&nbsp;e<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;where&nbsp;d.lockwait&nbsp;=&nbsp;e.kaddr)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;and&nbsp;a.sid&nbsp;=&nbsp;b.sid<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;and&nbsp;b.request&nbsp;=&nbsp;0<BR><BR>----&nbsp;执行得也十分缓慢。因而，往往只好通过将&nbsp;v$session&nbsp;中状态为"inactive"（不活动）并且最后一次进行操作时间至当前已超过&nbsp;20&nbsp;分钟以上(last_call_et&gt;20*60&nbsp;秒)的用户进程清除，然后才使得问题得到解决。&nbsp;<BR>----&nbsp;但是，这种方法实际上是"把婴儿与脏水一起泼掉"。因为，有些用户的进程尽管也为"inactive"，并且也已有较长时间未活动，但是，那是由于他们处于锁等待状态。&nbsp;<BR><BR>----&nbsp;因而，我想出了一个解决办法。即通过将问题发生时的&nbsp;v$lock，v$session视图中的相关记录保存于自己建立的表中，再对该表进行查询，则速度大大提高，可以迅速发现问题。经实际使用，效果非常好。在接到用户反映后，几秒钟即可查出由于锁住资源而影响其它用户的进程，并进行相应的处理。&nbsp;<BR><BR>----&nbsp;<FONT color=#f70968>首先</FONT>，以&nbsp;dba&nbsp;身份（不一定为system）登录入数据库中，创建三个基本表:my_session，my_lock,&nbsp;my_sqltext，并在将会进行查询的列上建立相应的索引。语句如下：&nbsp;rem&nbsp;从&nbsp;v$session&nbsp;视图中取出关心的字段，创建&nbsp;my_session&nbsp;表,并在查询要用到的字段上创建索引，以加快查询速度&nbsp;<BR><BR>drop&nbsp;table&nbsp;my_session;<BR>create&nbsp;table&nbsp;my_session<BR>as<BR>select&nbsp;a.username,&nbsp;a.sid,&nbsp;a.serial#,<BR>a.lockwait,&nbsp;a.machine,a.status,<BR>a.last_call_et,a.sql_hash_value,a.program<BR>&nbsp;&nbsp;from&nbsp;v$session&nbsp;a<BR>&nbsp;where&nbsp;1=2&nbsp;;<BR><BR>create&nbsp;unique&nbsp;index&nbsp;my_session_u1&nbsp;on&nbsp;my_session(sid);<BR>create&nbsp;index&nbsp;my_session_n2&nbsp;on&nbsp;my_session(lockwait);<BR>create&nbsp;index&nbsp;my_session_n3&nbsp;on&nbsp;my_session(sql_hash_value);<BR><BR>----&nbsp;rem&nbsp;从&nbsp;v$lock&nbsp;视图中取出字段，创建&nbsp;my_lock&nbsp;表，并在查询要用到的字段上创建索引，以加快查询速度&nbsp;<BR>drop&nbsp;table&nbsp;my_lock;<BR>create&nbsp;table&nbsp;my_lock<BR>as<BR>select&nbsp;id1,&nbsp;kaddr,&nbsp;sid,&nbsp;request,type<BR>&nbsp;&nbsp;from&nbsp;v$lock<BR>&nbsp;where&nbsp;1=2;<BR><BR>create&nbsp;index&nbsp;my_lock_n1&nbsp;on&nbsp;my_lock(sid);<BR>create&nbsp;index&nbsp;my_lock_n2&nbsp;on&nbsp;my_lock(kaddr);<BR><BR>----&nbsp;rem&nbsp;从&nbsp;v$sqltext&nbsp;视图中取出字段，创建&nbsp;my_sqltext&nbsp;表，并在查询要用到的字段上创建索引，以加快查询速度&nbsp;<BR>drop&nbsp;table&nbsp;my_sqltext;<BR>create&nbsp;table&nbsp;my_sqltext<BR>as<BR>select&nbsp;hash_value&nbsp;,&nbsp;sql_text<BR>&nbsp;&nbsp;from&nbsp;v$sqltext<BR>&nbsp;where&nbsp;1=2;<BR><BR>create&nbsp;index&nbsp;my_sqltext_n1&nbsp;on&nbsp;my_sqltext&nbsp;(&nbsp;hash_value);<BR><BR>----&nbsp;<FONT color=#f70968>然后</FONT>，创建一个&nbsp;SQL&nbsp;脚本文件，以便需要时可从&nbsp;SQL*Plus&nbsp;中直接调用。其中，首先用&nbsp;truncate&nbsp;table&nbsp;表名命令将表中的记录删除。之所以用&nbsp;truncate&nbsp;命令，而不是用delete&nbsp;命令，是因为delete&nbsp;命令执行时，将会产生重演记录，速度较慢，而且索引所占的空间并未真正释放，若反复做&nbsp;insert及delete,则索引所占的空间会不断增长，查询速度也会变慢。而&nbsp;truncate命令不产生重演记录，速度执行较delete快，而且索引空间被相应地释放出来。删除记录后，再将三个视图中的相关记录插入自己创建的三个表中。最后，对其进行查询，由于有索引，同时由于在插入时条件过滤后，记录数相对来说较少，因而查询速度很快，马上可以看到其结果。&nbsp;<BR>----&nbsp;此时，若发现该阻塞其它用户进程的进程是正常操作中，则可通知该用户对其进行提交，从而达到释放锁资源的目的；若为未正常操作，即，其状态为"inactive"，且其last_call_et已为较多长时间，则可执行以下语句将该进程进行清除，系统会自动对其进行回滚，从而释放锁住的资源。&nbsp;<BR><BR>&nbsp;&nbsp;&nbsp;alter&nbsp;system&nbsp;kill&nbsp;session&nbsp;'sid,&nbsp;serial#';&nbsp;&nbsp;<BR>----&nbsp;SQL&nbsp;脚本如下：&nbsp;<BR>set&nbsp;echo&nbsp;off<BR>set&nbsp;feedback&nbsp;off<BR>prompt&nbsp;'删除旧记录.....'<BR>truncate&nbsp;table&nbsp;my_session;<BR>truncate&nbsp;table&nbsp;my_lock;<BR>truncate&nbsp;table&nbsp;my_sqltext;<BR><BR>prompt&nbsp;'获取数据.....'<BR>insert&nbsp;into&nbsp;my_session<BR>select&nbsp;a.username,&nbsp;a.sid,&nbsp;a.serial#,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;a.lockwait,&nbsp;a.machine,a.status,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;a.last_call_et,a.sql_hash_value,a.program<BR>&nbsp;&nbsp;from&nbsp;v$session&nbsp;a<BR>&nbsp;where&nbsp;nvl(a.username,'NULL')&lt;&nbsp;&gt;'NULL;<BR><BR>insert&nbsp;into&nbsp;my_lock<BR>select&nbsp;id1,&nbsp;kaddr,&nbsp;sid,&nbsp;request,type<BR>&nbsp;&nbsp;from&nbsp;v$lock;<BR><BR>insert&nbsp;into&nbsp;my_sqltext<BR>select&nbsp;hash_value&nbsp;,&nbsp;sql_text<BR>&nbsp;&nbsp;from&nbsp;v$sqltext&nbsp;s,&nbsp;my_session&nbsp;m<BR>&nbsp;where&nbsp;s.hash_value=m.sql_hash_value;<BR><BR>column&nbsp;username&nbsp;format&nbsp;a10<BR>column&nbsp;machine&nbsp;format&nbsp;a15<BR>column&nbsp;last_call_et&nbsp;format&nbsp;99999&nbsp;heading&nbsp;"Seconds"<BR>column&nbsp;sid&nbsp;format&nbsp;9999<BR><BR>prompt&nbsp;"正在等待别人的用户"<BR>select&nbsp;a.sid,&nbsp;a.serial#,&nbsp;<BR>a.machine,a.last_call_et,&nbsp;a.username,&nbsp;b.id1<BR>&nbsp;&nbsp;from&nbsp;my_session&nbsp;a,&nbsp;my_lock&nbsp;b<BR>&nbsp;where&nbsp;a.lockwait&nbsp;=&nbsp;b.kaddr;<BR><BR>prompt&nbsp;"被等待的用户"<BR>select&nbsp;a.sid,&nbsp;a.serial#,&nbsp;<BR>a. machine,&nbsp;&nbsp;a.last_call_et,a.username,<BR>b. &nbsp;b.type,a.status,b.id1<BR>&nbsp;&nbsp;from&nbsp;my_session&nbsp;a,&nbsp;my_lock&nbsp;b<BR>&nbsp;where&nbsp;b.id1&nbsp;in<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(select&nbsp;distinct&nbsp;e.id1<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;from&nbsp;my_session&nbsp;d,&nbsp;my_lock&nbsp;e<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;where&nbsp;d.lockwait&nbsp;=&nbsp;e.kaddr)<BR>&nbsp;&nbsp;&nbsp;and&nbsp;a.sid&nbsp;=&nbsp;b.sid<BR>&nbsp;&nbsp;&nbsp;and&nbsp;b.request=0;<BR><BR>prompt&nbsp;"查出其&nbsp;&nbsp;sql&nbsp;"<BR>select&nbsp;a.username,&nbsp;a.sid,&nbsp;a.serial#,<BR>&nbsp;b.id1,&nbsp;b.type,&nbsp;c.sql_text<BR>&nbsp;&nbsp;from&nbsp;my_session&nbsp;a,&nbsp;my_lock&nbsp;b,&nbsp;my_sqltext&nbsp;c<BR>&nbsp;where&nbsp;b.id1&nbsp;in<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(select&nbsp;distinct&nbsp;e.id1<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;from&nbsp;my_session&nbsp;d,&nbsp;my_lock&nbsp;e<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;where&nbsp;d.lockwait&nbsp;=&nbsp;e.kaddr)<BR>&nbsp;&nbsp;&nbsp;and&nbsp;a.sid&nbsp;=&nbsp;b.sid<BR>&nbsp;&nbsp;&nbsp;and&nbsp;b.request=0<BR>&nbsp;&nbsp;&nbsp;and&nbsp;c.hash_value&nbsp;=a.sql_hash_value;<BR>&nbsp;&nbsp;<BR>----&nbsp;以上思路也可用于其它大型数据库系统如&nbsp;Informix,&nbsp;Sybase,DB2中。通过使用该脚本，可以极大地提高获取系统中当前锁等待的情况，从而及时解决数据库应用系统中的锁等待问题。而且，由于实际上已取出其&nbsp;program&nbsp;名及相应的&nbsp;sql&nbsp;语句，故可以在事后将其记录下来，交给其开发人员进行分析并从根本上得到解决。</P><BR><BR></DIV><img src ="http://www.cnitblog.com/yide/aggbug/6844.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/yide/" target="_blank">yide</a> 2006-02-22 16:34 <a href="http://www.cnitblog.com/yide/archive/2006/02/22/6844.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>FW : ORACLE备份策略</title><link>http://www.cnitblog.com/yide/archive/2006/02/22/6841.html</link><dc:creator>yide</dc:creator><author>yide</author><pubDate>Wed, 22 Feb 2006 08:27:00 GMT</pubDate><guid>http://www.cnitblog.com/yide/archive/2006/02/22/6841.html</guid><wfw:comment>http://www.cnitblog.com/yide/comments/6841.html</wfw:comment><comments>http://www.cnitblog.com/yide/archive/2006/02/22/6841.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cnitblog.com/yide/comments/commentRss/6841.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/yide/services/trackbacks/6841.html</trackback:ping><description><![CDATA[前言&nbsp;<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;这篇文章，本是我为CSDN写的，面向对象为中低用户，但考虑到这里也有人问过这样<BR><BR>的问题，偶就往这里也复制一份。在读该文章之前，建议对ORACLE构架有所了解，因为<BR><BR>ORACLE的备份与恢复，都是与ORACLE的构架紧密相关的，特别是ORACLE的SCN。<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;关于备份与恢复的文章，网上也有不少，进入Google,输入ORACLE备份，点击搜索，<BR><BR>我相信搜索出来的记录没有一个人能读完，但是大部分不是太老，也就是太不完全，很早我<BR><BR>就想总结一下了，我的这篇文章，主旨并不是说大家读了这篇文章，就会了备份的相关知<BR><BR>识，它仅仅也是一个提示，希望大家能从中得到益处。<BR><BR>概要&nbsp;<BR>1、了解什么是备份&nbsp;<BR>2、了解备份的重要性&nbsp;<BR>3、理解数据库的两种运行方式&nbsp;<BR>4、理解不同的备份方式及其区别&nbsp;<BR>5、了解正确的备份策略及其好处&nbsp;<BR><BR>一、了解备份的重要性&nbsp;<BR><BR>可以说，从计算机系统出世的那天起，就有了备份这个概念，计算机以其强大的速度处理能力，<BR><BR>取代了很多人为的工作，但是，往往很多时候，它又是那么弱不禁风，主板上的芯片、主板电<BR><BR>路、内存、电源等任何一项不能正常工作，都会导致计算机系统不能正常工作。当然，这些损坏<BR><BR>可以修复，不会导致应用和数据的损坏。但是，如果计算机的硬盘损坏，将会导致数据丢失，此<BR><BR>时必须用备份恢复数据。&nbsp;<BR><BR>其实，在我们的现实世界中，已经就存在很多备份策略，如RAID技术，双机热备，集群技术发<BR><BR>展的不就是计算机系统的备份和高可用性吗？有很多时候，系统的备份的确就能解决数据库备份<BR><BR>的问题，如磁盘介质的损坏，往往从镜相上面做简单的恢复，或简单的切换机器就可以了。&nbsp;<BR><BR>但是，上面所说的系统备份策略是从硬件的角度来考虑备份与恢复的问题，这是需要代价的。我<BR><BR>们所能选择备份策略的依据是：丢是数据的代价与确保数据不丢失的代价之比。还有的时候，硬<BR><BR>件的备份有时根本满足不了现实需要，假如你误删了一个表，但是你又想恢复的时候，数据库的<BR><BR>备份就变的重要了。ORACLE本身就提供了强大的备份与恢复策略，这里我们只讨论ORACLE<BR><BR>备份策略，以下的备份都是指ORACLE数据库备份，恢复将放到下一讲中。<BR>&nbsp;<BR>所谓备份，就是把数据库复制到转储设备的过程。其中，转储设备是指用于放置数据库拷贝的磁<BR><BR>带或磁盘。&nbsp;<BR><BR>能够进行什么样的恢复依赖于有什么样的备份。作为&nbsp;DBA，有责任从以下三个方面维护数据库<BR><BR>的可恢复性：&nbsp;<BR><BR>·使数据库的失效次数减到最少，从而使数据库保持最大的可用性；&nbsp;<BR><BR>·当数据库不可避免地失效后，要使恢复时间减到最少，从而使恢复的效率达到最高；&nbsp;<BR><BR>·当数据库失效后，要确保尽量少的数据丢失或根本不丢失，从而使数据具有最大的可恢复<BR><BR>性。&nbsp;<BR><BR>灾难恢复的最重要的工作是设计充足频率的硬盘备份过程。备份过程应该满足系统要求的可恢复<BR><BR>性。例如，如果数据库可有较长的关机时间，则可以每周进行一次冷备份，并归档重做日志，对<BR><BR>于24*7的系统，或许我们考虑的只能是热备份。&nbsp;如果每天都能备份当然会很理想，但要考虑其<BR><BR>现实性。企业都在想办法降低维护成本，现实的方案才可能被采用。只要仔细计划，并想办法达<BR><BR>到数据库可用性的底线，花少量的钱进行成功的备份与恢复也是可能的。&nbsp;<BR><BR>二、了解ORACLE的运行方式&nbsp;<BR><BR>ORACLE数据库有两种运行方式：一是归档方式（ARCHIVELOG），归档方式的目的是当数据<BR><BR>库发生故障时最大限度恢复数据库，可以保证不丢失任何已提交的数据；二是不归档方式<BR><BR>(NOARCHIVELOG)，只能恢复数据库到最近的回收点（冷备份或是逻辑备份）。我们根据数据<BR><BR>库的高可用性和用户可承受丢失的工作量的多少，对于生产数据库，强烈要求采用为归档方式；<BR><BR>那些正在开发和调试的数据库可以采用不归档方式。&nbsp;<BR><BR>如何改变数据库的运行方式，在创建数据库时，作为创建数据库的一部分，就决定了数据库初始<BR><BR>的存档方式。一般情况下为NOARCHIVELOG方式。当数据库创建好以后，根据我们的需要把<BR><BR>需要运行在归档方式的数据库改成ARCHIVELOG方式。&nbsp;<BR><BR>1、改变不归档方式为为归档方式&nbsp;<BR><BR>a.关闭数据库，备份已有的数据，改变数据库的运行方式是对数据库的重要改动，所以要对数据<BR><BR>库做备份，对可能出现的问题作出保护。&nbsp;<BR><BR>b.&nbsp;修改初试化参数，使能自动存档&nbsp;<BR><BR>修改（添加）初始化文件init[SID].ora参数：&nbsp;<BR><BR>log_archive_start=true&nbsp;#启动自动归档&nbsp;<BR><BR>log_archive_format=ARC%T%S.arc&nbsp;#归档文件格式&nbsp;<BR><BR>log_archive_dest=/arch12/arch&nbsp;#归档路径&nbsp;<BR><BR>在8i中，可以最多有五个归档路径，并可以归档到其它服务器，如备用数据库(standby&nbsp;<BR><BR>database)服务器&nbsp;<BR><BR>c.启动Instance到Mount状态，即加载数据库但不打开数据库：&nbsp;<BR><BR>$&gt;SVRMGRL&nbsp;<BR>SVRMGRL&nbsp;&gt;connect&nbsp;internal&nbsp;<BR>SVRMGRL&nbsp;&gt;startup&nbsp;mount&nbsp;<BR>&nbsp;&nbsp;&nbsp;d.发出修改命令&nbsp;<BR>SVRMGRL&nbsp;&gt;alter&nbsp;database&nbsp;archivelog;&nbsp;<BR>SVRMGRL&gt;alter&nbsp;database&nbsp;open;&nbsp;<BR><BR>2、改变归档状态为不归档状态&nbsp;<BR><BR>&nbsp;&nbsp;&nbsp;与以上步骤相同，但有些操作不一样，主要是在以上的b操作中，现在为删除或注释该参数，<BR><BR>在d操作中，命令为&nbsp;<BR><BR>SVRMGRL&nbsp;&gt;alter&nbsp;database&nbsp;noarchivelog;&nbsp;<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;注意，从归档方式转换到非归档方式后一定要做一次数据库的全冷备份，防止意外事件的发<BR><BR>生。&nbsp;<BR><img src ="http://www.cnitblog.com/yide/aggbug/6841.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/yide/" target="_blank">yide</a> 2006-02-22 16:27 <a href="http://www.cnitblog.com/yide/archive/2006/02/22/6841.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>FW : ORACLE 数据库管理员的职责</title><link>http://www.cnitblog.com/yide/archive/2006/02/22/6839.html</link><dc:creator>yide</dc:creator><author>yide</author><pubDate>Wed, 22 Feb 2006 08:23:00 GMT</pubDate><guid>http://www.cnitblog.com/yide/archive/2006/02/22/6839.html</guid><wfw:comment>http://www.cnitblog.com/yide/comments/6839.html</wfw:comment><comments>http://www.cnitblog.com/yide/archive/2006/02/22/6839.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/yide/comments/commentRss/6839.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/yide/services/trackbacks/6839.html</trackback:ping><description><![CDATA[<A href="http://www.dbonline.cn/" target=_blank><STRONG><FONT color=#4a664d>http://www.dbonline.cn</FONT></STRONG></A> <BR><BR>ORACLE&nbsp;数据库管理员应按如下方式对&nbsp;ORACLE&nbsp;数据库系统做定期监控：&nbsp;<BR>(1).&nbsp;每天对&nbsp;ORACLE&nbsp;数据库的运行状态&nbsp;,&nbsp;日志文件&nbsp;,&nbsp;备份情况&nbsp;,&nbsp;数据库<BR>的空间使用情况&nbsp;,&nbsp;系统资源的使用情况进行检查&nbsp;,&nbsp;发现并解决问题。<BR>(2).&nbsp;每周对数据库对象的空间扩展情况&nbsp;,&nbsp;数据的增长情况进行监控&nbsp;,&nbsp;对数<BR>据库做健康检查&nbsp;,&nbsp;对数据库对象的状态做检查。<BR>(3).&nbsp;每月对表和索引等进行&nbsp;Analyze,&nbsp;检查表空间碎片&nbsp;,&nbsp;寻找数据库性能<BR>调整的机会&nbsp;,&nbsp;进行数据库性能调整&nbsp;,&nbsp;提出下一步空间管理计划。对ORACLE<BR>数据库状态进行一次全面检查。<BR>&nbsp;<BR><STRONG>每天的工作</STRONG>&nbsp;<BR>(1).&nbsp;确认所有的&nbsp;INSTANCE&nbsp;状态正常&nbsp;<BR>登陆到所有数据库或例程&nbsp;,&nbsp;检测&nbsp;ORACLE&nbsp;后台进程&nbsp;:&nbsp;$ps&nbsp;–ef|grep&nbsp;ora&nbsp;<BR>(2).&nbsp;检查文件系统的使用（剩余空间）。<BR>如果文件系统的剩余空间小于20%&nbsp;，需删除不用的文件以释放空间。<BR>$df&nbsp;–k&nbsp;<BR>(3).&nbsp;检查日志文件和&nbsp;trace&nbsp;文件记录&nbsp;alert&nbsp;和&nbsp;trace&nbsp;文件中的错误。&nbsp;<BR>连接到每个需管理的系统&nbsp;<BR>?&nbsp;使用'&nbsp;telnet&nbsp;'&nbsp;<BR>?&nbsp;对每个数据库&nbsp;,cd&nbsp;到&nbsp;bdump&nbsp;目录&nbsp;,&nbsp;通常是$ORACLE_BASE/&lt;SID&gt;/bdump&nbsp;<BR>?&nbsp;使用&nbsp;Unix&nbsp;‘tail'&nbsp;命令来查看&nbsp;alert_&lt;SID&gt;.log&nbsp;文件<BR>?&nbsp;如果发现任何新的&nbsp;ORA-&nbsp;错误&nbsp;,&nbsp;记录并解决&nbsp;<BR>(4).&nbsp;检查数据库当日备份的有效性。&nbsp;<BR>对&nbsp;RMAN&nbsp;备份方式&nbsp;:&nbsp;<BR>检查第三方备份工具的备份日志以确定备份是否成功&nbsp;<BR>对&nbsp;EXPORT&nbsp;备份方式&nbsp;:&nbsp;<BR>检查&nbsp;exp&nbsp;日志文件以确定备份是否成功&nbsp;<BR>对其他备份方式&nbsp;:&nbsp;<BR>检查相应的日志文件&nbsp;<BR>(5).&nbsp;检查数据文件的状态记录状态不是“&nbsp;online”&nbsp;的数据文件，并做恢复。&nbsp;<BR>Select&nbsp;file_name&nbsp;from&nbsp;dba_data_files&nbsp;where&nbsp;status='OFFLINE'&nbsp;<BR>(6).&nbsp;检查表空间的使用情况&nbsp;<BR>SELECT&nbsp;tablespace_name,&nbsp;max_m,&nbsp;count_blocks&nbsp;free_blk_cnt,&nbsp;<BR>sum_free_m,to_char(100*sum_free_m/sum_m,&nbsp;'99.99')&nbsp;||&nbsp;'%'&nbsp;AS&nbsp;<BR>pct_free&nbsp;<BR>FROM&nbsp;(&nbsp;SELECT&nbsp;tablespace_name,sum(bytes)/1024/1024&nbsp;AS&nbsp;<BR>sum_m&nbsp;FROM&nbsp;dba_data_files&nbsp;GROUP&nbsp;BY&nbsp;tablespace_name),&nbsp;<BR>(&nbsp;SELECT&nbsp;tablespace_name&nbsp;AS&nbsp;fs_ts_name,&nbsp;max<BR>(bytes)/1024/1024&nbsp;AS&nbsp;max_m,&nbsp;count(blocks)&nbsp;AS&nbsp;count_blocks,&nbsp;<BR>sum(bytes/1024/1024)&nbsp;AS&nbsp;sum_free_m&nbsp;FROM&nbsp;dba_free_space&nbsp;<BR>GROUP&nbsp;BY&nbsp;tablespace_name&nbsp;)&nbsp;<BR>WHERE&nbsp;tablespace_name&nbsp;=&nbsp;fs_ts_name&nbsp;<BR>(7).&nbsp;检查剩余表空间&nbsp;<BR>SELECT&nbsp;tablespace_name,&nbsp;sum&nbsp;(&nbsp;blocks&nbsp;)&nbsp;as&nbsp;free_blk&nbsp;,&nbsp;<BR>trunc&nbsp;(&nbsp;sum&nbsp;(&nbsp;bytes&nbsp;)&nbsp;/(1024*1024)&nbsp;)&nbsp;as&nbsp;free_m,&nbsp;<BR>max&nbsp;(&nbsp;bytes&nbsp;)&nbsp;/&nbsp;(1024)&nbsp;as&nbsp;big_chunk_k,&nbsp;count&nbsp;(*)&nbsp;as&nbsp;num_chunks&nbsp;<BR>FROM&nbsp;dba_free_space&nbsp;GROUP&nbsp;BY&nbsp;tablespace_name;&nbsp;<BR>(8).&nbsp;监控数据库性能&nbsp;<BR>运行&nbsp;bstat/estat&nbsp;生成系统报告&nbsp;<BR>或者使用&nbsp;statspack&nbsp;收集统计数据&nbsp;<BR>(9).&nbsp;检查数据库性能，记录数据库的&nbsp;cpu&nbsp;使用、&nbsp;IO&nbsp;、&nbsp;buffer&nbsp;命中率等等<BR>使用&nbsp;vmstat,iostat,glance,top&nbsp;等命令&nbsp;<BR>(10).&nbsp;日常出现问题的处理。<BR>&nbsp;<BR><STRONG>每周的工作</STRONG>&nbsp;<BR>(1).&nbsp;控数据库对象的空间扩展情况&nbsp;<BR>根据本周每天的检查情况找到空间扩展很快的数据库对象&nbsp;,&nbsp;并采取相&nbsp;<BR>应的措施&nbsp;<BR>--&nbsp;删除历史数据&nbsp;<BR>---&nbsp;扩表空间&nbsp;<BR>alter&nbsp;tablespace&nbsp;&lt;name&gt;&nbsp;add&nbsp;datafile&nbsp;‘&lt;file&gt;'&nbsp;size&nbsp;&lt;size&gt;&nbsp;<BR>---&nbsp;调整数据对象的存储参数&nbsp;<BR>next&nbsp;extent&nbsp;<BR>pct_increase&nbsp;<BR>(2).&nbsp;监控数据量的增长情况&nbsp;<BR>根据本周每天的检查情况找到记录数量增长很快的数据库对象&nbsp;,&nbsp;并采&nbsp;<BR>取相应的措施&nbsp;<BR>--&nbsp;删除历史数据&nbsp;<BR>---&nbsp;扩表空间&nbsp;<BR>alter&nbsp;tablespace&nbsp;&lt;name&gt;&nbsp;add&nbsp;datafile&nbsp;‘&lt;file&gt;'&nbsp;size&nbsp;&lt;size&gt;&nbsp;<BR>(3).&nbsp;系统健康检查&nbsp;<BR>检查以下内容&nbsp;:&nbsp;<BR>init&lt;sid&gt;.ora&nbsp;<BR>controlfile&nbsp;<BR>redo&nbsp;log&nbsp;file&nbsp;<BR>archiving&nbsp;<BR>sort&nbsp;area&nbsp;size&nbsp;<BR>tablespace(system,temporary,tablespace&nbsp;fragment)&nbsp;<BR>datafiles(autoextend,location)&nbsp;<BR>object(number&nbsp;of&nbsp;extent,next&nbsp;extent,index)&nbsp;<BR>rollback&nbsp;segment&nbsp;<BR>logging&nbsp;&amp;tracing(alert.log,max_dump_file_size,sqlnet)&nbsp;<BR>(4).&nbsp;检查无效的数据库对象&nbsp;<BR>SELECT&nbsp;owner,&nbsp;object_name,&nbsp;object_type&nbsp;FROM&nbsp;dba_objects&nbsp;<BR>WHERE&nbsp;status=&nbsp;'&nbsp;INVALID&nbsp;'。&nbsp;<BR>(5).&nbsp;检查不起作用的约束&nbsp;<BR>SELECT&nbsp;owner,&nbsp;constraint_name,&nbsp;table_name,&nbsp;<BR>constraint_type,&nbsp;status&nbsp;<BR>FROM&nbsp;dba_constraints&nbsp;<BR>WHERE&nbsp;status&nbsp;=&nbsp;'DISABLED'&nbsp;AND&nbsp;constraint_type&nbsp;=&nbsp;'P'&nbsp;<BR>(6).&nbsp;检查无效的&nbsp;trigger&nbsp;<BR>SELECT&nbsp;owner,&nbsp;trigger_name,&nbsp;table_name,&nbsp;status&nbsp;<BR>FROM&nbsp;dba_triggers&nbsp;<BR>WHERE&nbsp;status&nbsp;=&nbsp;'DISABLED'&nbsp;<BR><BR><STRONG>每月的工作</STRONG>&nbsp;<BR>(1).&nbsp;Analyze&nbsp;Tables/Indexes/Cluster&nbsp;<BR>analyze&nbsp;table&nbsp;&lt;name&gt;&nbsp;estimate&nbsp;statistics&nbsp;sample&nbsp;50&nbsp;percent;&nbsp;<BR>(2).&nbsp;检查表空间碎片&nbsp;<BR>根据本月每周的检查分析数据库碎片情况&nbsp;,&nbsp;找到相应的解决方法&nbsp;<BR>(3).&nbsp;寻找数据库性能调整的机会&nbsp;<BR>比较每天对数据库性能的监控报告&nbsp;,&nbsp;确定是否有必要对数据库性能进行调整&nbsp;<BR>(4).&nbsp;数据库性能调整&nbsp;<BR>如有必要&nbsp;,&nbsp;进行性能调整&nbsp;<BR>(5).&nbsp;提出下一步空间管理计划&nbsp;<BR>根据每周的监控&nbsp;,&nbsp;提出空间管理的改进方法<BR><img src ="http://www.cnitblog.com/yide/aggbug/6839.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/yide/" target="_blank">yide</a> 2006-02-22 16:23 <a href="http://www.cnitblog.com/yide/archive/2006/02/22/6839.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>FW : Oracle DBA 日常管理</title><link>http://www.cnitblog.com/yide/archive/2006/02/22/6838.html</link><dc:creator>yide</dc:creator><author>yide</author><pubDate>Wed, 22 Feb 2006 08:20:00 GMT</pubDate><guid>http://www.cnitblog.com/yide/archive/2006/02/22/6838.html</guid><wfw:comment>http://www.cnitblog.com/yide/comments/6838.html</wfw:comment><comments>http://www.cnitblog.com/yide/archive/2006/02/22/6838.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/yide/comments/commentRss/6838.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/yide/services/trackbacks/6838.html</trackback:ping><description><![CDATA[<P>目的：这篇文档有很详细的资料记录着对一个甚至更多的&nbsp;ORACLE&nbsp;数据库每天的，每月的，每年的运行的状态的结果及检查的结果，在文档的附录中你将会看到所有检查，修改的SQL和&nbsp;PL/SQL&nbsp;代码。&nbsp; </P>
<P>目录&nbsp;<BR><BR>1.&nbsp;日常维护程序&nbsp;<BR>A&nbsp;．&nbsp;检查已起的所有实例&nbsp;<BR>B&nbsp;．&nbsp;查找一些新的警告日志&nbsp;<BR>C&nbsp;．&nbsp;检查&nbsp;DBSNMP&nbsp;是否在运行&nbsp;<BR>D&nbsp;．&nbsp;检查数据库备份是否正确&nbsp;<BR>E&nbsp;．&nbsp;检查备份到磁带中的文件是否正确&nbsp;<BR>F&nbsp;．&nbsp;检查数据库的性能是否正常合理，是否有足够的空间和资源&nbsp;<BR>G&nbsp;．&nbsp;将文档日志复制到备份的数据库中&nbsp;<BR>H&nbsp;．&nbsp;要常看&nbsp;DBA&nbsp;用户手册&nbsp;<BR>2.&nbsp;晚间维护程序&nbsp;<BR>A&nbsp;．收集&nbsp;VOLUMETRIC&nbsp;的数据&nbsp;<BR>3.&nbsp;每周维护工作&nbsp;<BR>A&nbsp;．&nbsp;查找那些破坏规则的&nbsp;OBJECT&nbsp;<BR>B&nbsp;．&nbsp;查找是否有违反安全策略的问题&nbsp;<BR>C&nbsp;．&nbsp;查看错误地方的&nbsp;SQL*NET&nbsp;日志&nbsp;<BR>D&nbsp;．&nbsp;将所有的警告日志存档&nbsp;<BR>E&nbsp;．&nbsp;经常访问供应商的主页&nbsp;<BR>4.&nbsp;月维护程序&nbsp;<BR>A&nbsp;．&nbsp;查看对数据库会产生危害的增长速度&nbsp;<BR>B&nbsp;．&nbsp;回顾以前数据库优化性能的调整&nbsp;<BR>C&nbsp;．&nbsp;查看&nbsp;I/O&nbsp;的屏颈问题&nbsp;<BR>D&nbsp;．&nbsp;回顾&nbsp;FRAGMENTATION&nbsp;<BR>E&nbsp;．&nbsp;将来的执行计划&nbsp;<BR>F&nbsp;．&nbsp;查看调整点和维护&nbsp;<BR>5.&nbsp;附录&nbsp;<BR>A&nbsp;．&nbsp;月维护过程&nbsp;<BR>B&nbsp;．&nbsp;晚间维护过程&nbsp;<BR>C&nbsp;．&nbsp;周维护过程&nbsp;<BR>6.&nbsp;参考文献&nbsp;<BR>----------------------------------------------------------------&nbsp;<BR><BR><STRONG>一．日维护过程</STRONG>&nbsp;<BR><BR>A&nbsp;．查看所有的实例是否已起&nbsp;<BR>确定数据库是可用的，把每个实例写入日志并且运行日报告或是运行测试&nbsp;<BR>文件。当然有一些操作我们是希望它能自动运行的。&nbsp;<BR>可选择执行：用&nbsp;ORACLE&nbsp;管理器中的‘&nbsp;PROBE'&nbsp;事件来查看&nbsp;<BR>B&nbsp;．查找新的警告日志文件&nbsp;<BR>1.&nbsp;联接每一个操作管理系统&nbsp;<BR>2.&nbsp;使用‘&nbsp;TELNET'&nbsp;或是可比较程序&nbsp;<BR>3.&nbsp;对每一个管理实例，经常的执行&nbsp;$ORACLE_BASE/&lt;SID&gt;/bdump&nbsp;操&nbsp;<BR>作，并使其能回退到控制数据库的&nbsp;SID&nbsp;。&nbsp;<BR>4.&nbsp;在提示下，使用&nbsp;UNIX&nbsp;中的‘&nbsp;TAIL&nbsp;'命令查看&nbsp;alert_&lt;SID&gt;.log&nbsp;，或是&nbsp;<BR>用其他方式检查文件中最近时期的警告日志&nbsp;<BR>5.&nbsp;如果以前出现过的一些&nbsp;ORA_ERRORS&nbsp;又出现，将它记录到数据库&nbsp;<BR>恢复日志中并且仔细的研究它们，这个数据库恢复日志在〈&nbsp;FILE&nbsp;〉中&nbsp;<BR>C&nbsp;．查看&nbsp;DBSNMP&nbsp;的运行情况&nbsp;<BR>检查每个被管理机器的‘&nbsp;DBSNMP'&nbsp;进程并将它们记录到日志中。&nbsp;<BR>在&nbsp;UNIX&nbsp;中，在命令行中，键入&nbsp;ps&nbsp;–ef&nbsp;|&nbsp;grep&nbsp;dbsnmp,&nbsp;将回看到&nbsp;2&nbsp;个&nbsp;<BR>DBSNMP&nbsp;进程在运行。如果没有，重启&nbsp;DBSNMP&nbsp;。&nbsp;<BR>D&nbsp;．查数据库备份是否成功&nbsp;<BR>E&nbsp;．检查备份的磁带文档是否成功&nbsp;<BR>F&nbsp;．检查对合理的性能来说是否有足够的资源&nbsp;<BR>1.&nbsp;检查在表空间中有没有剩余空间。&nbsp;<BR>对每一个实例来说，检查在表空间中是否存在有剩余空间来满足当天&nbsp;<BR>的预期的需要。当数据库中已有的数据是稳定的，数据日增长的平均&nbsp;<BR>数也是可以计算出来，最小的剩余空间至少要能满足每天数据的增&nbsp;长。&nbsp;<BR>A&nbsp;）&nbsp;运行‘&nbsp;FREE.SQL'&nbsp;来检查表空间的剩余空间。&nbsp;<BR>B&nbsp;）&nbsp;运行‘&nbsp;SPACE.SQL'&nbsp;来检查表空间中的剩余空间百分率&nbsp;<BR>2.&nbsp;检查回滚段&nbsp;<BR>回滚段的状态一般是在线的，除了一些为复杂工作准备的专用&nbsp;段，它一般状态是离线的。&nbsp;<BR>a)&nbsp;每个数据库都有一个回滚段名字的列表。&nbsp;<BR>b)&nbsp;你可以用&nbsp;V$ROLLSTAT&nbsp;来查询在线或是离线的回滚段的现在状&nbsp;态&nbsp;.&nbsp;<BR>c)&nbsp;对于所有回滚段的存储参数及名字，&nbsp;可用&nbsp;<BR>DBA_ROLLBACK_SEGS&nbsp;来查询。但是它不如&nbsp;V$ROLLSTAT&nbsp;准确。&nbsp;<BR>3.&nbsp;识别出一些过分的增长&nbsp;<BR>查看数据库中超出资源或是增长速度过大的段，这些段的存储参&nbsp;数需要调整。&nbsp;<BR>a&nbsp;）&nbsp;收集日数据大小的信息，&nbsp;可以用&nbsp;<BR>‘&nbsp;ANALYZE5PCT.SQL&nbsp;'。如果你收集的是每晚的信息，&nbsp;则可跳过这一步。&nbsp;<BR>b&nbsp;）&nbsp;检查当前的范围，可用‘&nbsp;NR.EXTENTS.SQL'&nbsp;。&nbsp;<BR>c&nbsp;）&nbsp;查询当前表的大小信息。&nbsp;<BR>d&nbsp;）&nbsp;查询当前索引大小的信息。&nbsp;<BR>e&nbsp;）&nbsp;查询增长趋势。&nbsp;<BR>4.&nbsp;确定空间的范围。&nbsp;<BR>如果范围空间对象的&nbsp;NEXT_EXTENT&nbsp;比表空间所能提供的最大范&nbsp;<BR>围还要大，那么这将影响数据库的运行。如果我们找到了这个目标，可&nbsp;<BR>以用‘&nbsp;ALTER&nbsp;TABLESPACE&nbsp;COALESCE'&nbsp;调查它的位置，或加另外&nbsp;的数据文件。&nbsp;<BR>A&nbsp;）运行‘&nbsp;SPACEBOUND.SQL'&nbsp;。如果都是正常的，将不返回任何行。&nbsp;<BR>5.&nbsp;回顾&nbsp;CPU&nbsp;，内存，网络，硬件资源论点的过程&nbsp;<BR>A&nbsp;）检查&nbsp;CPU&nbsp;的利用情况，进到&nbsp;x:webphase2default.htm&nbsp;=&gt;system&nbsp;<BR>metrics=&gt;CPU&nbsp;利用页，&nbsp;CPU&nbsp;的最大限度为&nbsp;400&nbsp;，当&nbsp;CPU&nbsp;的占用保持&nbsp;<BR>在&nbsp;350&nbsp;以上有一段时间的话，我们就需要查看及研究出现的问题。&nbsp;<BR>G&nbsp;．将存档日志复制到备用数据库中&nbsp;<BR>如果有一个备用数据库，将适当的存档日志复制到备用数据库的期望&nbsp;<BR>位置，备用数据库中保存最近期的数据。&nbsp;<BR>H.&nbsp;经常查阅&nbsp;DBA&nbsp;用户手册&nbsp;<BR>如果有可能的话，要广泛的阅读，包括&nbsp;DBA&nbsp;手册，行业杂志，新闻&nbsp;组或是邮件列表。&nbsp;<BR>-------------------------------------------------------------&nbsp;<BR><BR><STRONG>二．晚间维护过程&nbsp;<BR></STRONG><BR>大部分的数据库产品将受益于每晚确定的检查进程的运行。&nbsp;<BR>A.&nbsp;收集&nbsp;VOLUMETRIC&nbsp;数据&nbsp;<BR>1.&nbsp;分析计划和收集数据&nbsp;<BR>更准确的分析计算并保存结果。&nbsp;<BR>a&nbsp;）&nbsp;如果你现在没有作这些的话，用‘&nbsp;MK&nbsp;VOLFACT.SQL'&nbsp;来创建测定体积的&nbsp;表。&nbsp;<BR>b&nbsp;）&nbsp;收集晚间数据大小的信息，用‘&nbsp;ANALYZE&nbsp;COMP.SQL'&nbsp;。&nbsp;<BR>c&nbsp;）&nbsp;收集统计结果，用‘&nbsp;POP&nbsp;VOL.SQL'&nbsp;。&nbsp;<BR>d&nbsp;）&nbsp;在空闲的时候检查数据，可能的话，每周或每个月进行。&nbsp;<BR>我是用&nbsp;MS&nbsp;EXCEL&nbsp;和&nbsp;ODBC&nbsp;的联接来检查数据和图表的增长&nbsp;<BR>-------------------------------------------------------------&nbsp;<BR><STRONG><BR>三．每周维护过程</STRONG>&nbsp;<BR><BR>A&nbsp;．&nbsp;查找被破坏的目标&nbsp;<BR>1.&nbsp;对于每个给定表空间的对象来说，&nbsp;NEXT_EXTENT&nbsp;的大小是相同的，如&nbsp;<BR>12/14/98&nbsp;，缺省的&nbsp;NEXT_EXTENT&nbsp;的&nbsp;DATAHI&nbsp;为&nbsp;1G&nbsp;，&nbsp;DATALO&nbsp;为&nbsp;500MB&nbsp;，&nbsp;<BR>INDEXES&nbsp;为&nbsp;256MB&nbsp;。&nbsp;<BR>A&nbsp;）&nbsp;检查&nbsp;NEXT_EXTENT&nbsp;的设置，可用‘&nbsp;NEXTEXT&nbsp;。&nbsp;SQL'&nbsp;。&nbsp;<BR>B&nbsp;）&nbsp;检查已有的&nbsp;EXTENTS&nbsp;，可用‘&nbsp;EXISTEXT&nbsp;。&nbsp;SQL'&nbsp;。&nbsp;<BR>2.&nbsp;所有的表都应该有唯一的主键&nbsp;<BR>a&nbsp;）&nbsp;查看那些表没有主键，可用‘&nbsp;NO_PK.SQL'&nbsp;。&nbsp;<BR>b&nbsp;）&nbsp;查找那些主键是没有发挥作用的，可用‘&nbsp;DIS_PK.SQL'&nbsp;。&nbsp;<BR>c&nbsp;）&nbsp;所有作索引的主键都要是唯一的，可用‘&nbsp;NONUPK&nbsp;。&nbsp;SQL'&nbsp;来检&nbsp;查。&nbsp;<BR>3.&nbsp;所有的索引都要放到索引表空间中。运行‘&nbsp;MKREBUILD_IDX&nbsp;。&nbsp;SQL'&nbsp;<BR>4.&nbsp;不同的环境之间的计划应该是同样的，特别是测试环境和成品环境之间的&nbsp;计划应该相同。&nbsp;<BR>a&nbsp;）&nbsp;检查不同的&nbsp;2&nbsp;个运行环境中的数据类型是否一致，可用&nbsp;<BR>‘&nbsp;DATATYPE.SQL&nbsp;'。&nbsp;<BR>b&nbsp;）&nbsp;在&nbsp;2&nbsp;个不同的实例中寻找对象的不同点，&nbsp;可用&nbsp;<BR>‘&nbsp;OBJ_COORD.SQL&nbsp;'。&nbsp;<BR>c&nbsp;）&nbsp;更好的做法是，使用一种工具，象寻求软件的计划管理器那样的&nbsp;工具。&nbsp;<BR>B&nbsp;．&nbsp;查看是否有危害到安全策略的问题。&nbsp;<BR>C&nbsp;．&nbsp;查看报错的&nbsp;SQL*NET&nbsp;日志。&nbsp;<BR>1.&nbsp;客户端的日志。&nbsp;<BR>2.&nbsp;服务器端的日志。&nbsp;<BR>D&nbsp;．&nbsp;.&nbsp;将所有的警告日志存档&nbsp;<BR>E&nbsp;．&nbsp;.&nbsp;供应商的主页&nbsp;<BR>1.&nbsp;ORACLE&nbsp;供应商&nbsp;<BR><IMG alt=::URL:: hspace=2 src="http://www.blogcn.com/images/aurl.gif" align=absBottom border=0><A href="http://www.oracle.com/" target=_blank><STRONG><FONT color=#4a664d>http://www.oracle.com</FONT></STRONG></A> &nbsp;<BR><IMG alt=::URL:: hspace=2 src="http://www.blogcn.com/images/aurl.gif" align=absBottom border=0><A href="http://technet.oracle.com/" target=_blank><STRONG><FONT color=#4a664d>http://technet.oracle.com</FONT></STRONG></A> &nbsp;<BR><IMG alt=::URL:: hspace=2 src="http://www.blogcn.com/images/aurl.gif" align=absBottom border=0><A href="http://www.oracle.com/" target=_blank><STRONG><FONT color=#4a664d>http://www.oracle.com</FONT></STRONG></A> /support&nbsp;<BR><IMG alt=::URL:: hspace=2 src="http://www.blogcn.com/images/aurl.gif" align=absBottom border=0><A href="http://www.oramag.com/" target=_blank><STRONG><FONT color=#4a664d>http://www.oramag.com</FONT></STRONG></A> &nbsp;<BR>2.&nbsp;Quest&nbsp;Software&nbsp;<BR><IMG alt=::URL:: hspace=2 src="http://www.blogcn.com/images/aurl.gif" align=absBottom border=0><A href="http://www.quests.com/" target=_blank><STRONG><FONT color=#4a664d>http://www.quests.com</FONT></STRONG></A> &nbsp;<BR>3.&nbsp;Sun&nbsp;Microsystems&nbsp;<BR><IMG alt=::URL:: hspace=2 src="http://www.blogcn.com/images/aurl.gif" align=absBottom border=0><A href="http://www.sun.com/" target=_blank><STRONG><FONT color=#4a664d>http://www.sun.com</FONT></STRONG></A> &nbsp;<BR>----------------------------------------------------------------&nbsp;<BR><BR><STRONG>四．月维护过程&nbsp;</STRONG><BR><BR>A&nbsp;．查看对数据库会产生危害的增长速度&nbsp;<BR>1.&nbsp;从以前的记录或报告中回顾段增长的变化以此来确定段增长带来危害&nbsp;<BR>B&nbsp;．&nbsp;回顾以前数据库优化性能的调整&nbsp;<BR>1.&nbsp;回顾一般&nbsp;ORACLE&nbsp;数据库的调整点，比较以前的报告来确定有害的发展&nbsp;趋势。&nbsp;<BR>C&nbsp;．&nbsp;查看&nbsp;I/O&nbsp;的屏颈问题&nbsp;<BR>1.&nbsp;查看前期数据库文件的活动性，比较以前的输出来判断有可能导致屏颈&nbsp;问题的趋势。&nbsp;<BR>D&nbsp;．&nbsp;回顾&nbsp;FRAGMENTATION&nbsp;<BR>E&nbsp;．&nbsp;计划数据库将来的性能&nbsp;<BR>1.&nbsp;比较&nbsp;ORACLE&nbsp;和操作系统的&nbsp;CPU&nbsp;，内存，网络，及硬盘的利用率以此&nbsp;<BR>来确定在近期将会有的一些资源争夺的趋势&nbsp;<BR>2.&nbsp;当系统将超出范围时要把性能趋势当作服务水平的协议来看&nbsp;<BR>F&nbsp;．&nbsp;完成调整和维