﻿<?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>C++博客-tbwshc-随笔分类-oracle</title><link>http://www.cppblog.com/tbwshc/category/19592.html</link><description>tbw</description><language>zh-cn</language><lastBuildDate>Mon, 23 Jul 2012 04:26:30 GMT</lastBuildDate><pubDate>Mon, 23 Jul 2012 04:26:30 GMT</pubDate><ttl>60</ttl><item><title>Oracle容灾方案的选择 </title><link>http://www.cppblog.com/tbwshc/archive/2012/07/22/184604.html</link><dc:creator>tbwshc</dc:creator><author>tbwshc</author><pubDate>Sun, 22 Jul 2012 05:58:00 GMT</pubDate><guid>http://www.cppblog.com/tbwshc/archive/2012/07/22/184604.html</guid><description><![CDATA[<div>---- <span style="font-family: 宋体"  ?Times Roman? New Times>容灾首先是一个概念，要认识到为什么做容灾，才能做好容灾。世界上没有卖后悔药的，当灾难降临了，如果没有行之有效的数据保护、数据恢复的容灾措施，带来不可预估的损失将是无法避免的。类似电信行业、金融行业，证券行业也是如此，动辄涉及数以百亿计的资金、涉及庞大的客户量，在系统数据的准确、业务的连续、关键业务的不中断等方面更是不容出现任何的差错。</span> </div>
<div>&nbsp;</div>
<div>----<span style="font-family: 宋体"  ?Times Roman? New Times>目前，业界具有容灾功能的常用解决方案主要包括以下几类：磁盘阵列复制技术，主要由一些磁盘阵列厂商提供，如</span>EMC SRDF<span style="font-family: 宋体"  ?Times Roman? New Times>、</span>IBM PPRC <span style="font-family: 宋体"  ?Times Roman? New Times>、</span>HP BusinessCopy<span style="font-family: 宋体"  ?Times Roman? New Times>、</span>HDS TrueCopy<span style="font-family: 宋体"  ?Times Roman? New Times>等；存储卷复制技术，<a href="http://www.tbwshc.com"><span style="color: #000000">tb</span></a></span><span style="font-family: 宋体; color: #000000"  ?Times Roman? New Times>由一些卷管理软</span><span style="font-family: 宋体"  ?Times Roman? New Times>件厂商提供，如</span>VERITAS VVR<span style="font-family: 宋体"  ?Times Roman? New Times>；数据库复制技术，由数据库厂商以及一些第三方厂商提供，如</span>DSG RealSync<span style="font-family: 宋体"  ?Times Roman? New Times>，</span>Quest SharePlex<span style="font-family: 宋体"  ?Times Roman? New Times>等；应用层复制技术，由各系统的应用厂商自己提供。</span> </div>
<div>&nbsp;</div>
<div>----<span style="font-family: 宋体"  ?Times Roman? New Times>磁盘阵列复制技术主要适用于数据中心级的海量数据复制，此技术用户必需采用支持该功能的磁盘阵列型号，而这些阵列大都为高端阵列，投资非常昂贵。并且，由于政府行业用户的带宽有限，而磁盘阵列复制技术对带宽的要求又相对很高，动辄需要上</span>GB<span style="font-family: 宋体"  ?Times Roman? New Times>的带宽。此外，采用磁盘阵列复制技术，其目标端无法提供实时数据查询，由于目标端数据库在复制过程中不能被打开，难于实现交易与查询的分离，同时也造成大量投资浪费。因此，磁盘阵列复制技术无法满足某些行业集中交易系统的容灾需求，使得这些用户难以选择此种解决方案。</span> </div>
<div>&nbsp;</div>
<div>----<span style="font-family: 宋体"  ?Times Roman? New Times>存储卷复制技术主要适用于工作组级的数据复制，它对</span>CPU<span style="font-family: 宋体"  ?Times Roman? New Times>资源占用高。同样由于目标端数据无法提供实时数据查询和对带宽的要求高，使得证券等行业用户也难以选择。</span> </div>
<div>&nbsp;</div>
<div>----<span style="font-family: 宋体"  ?Times Roman? New Times>而应用层复制技术只适合那些在应用中提供了该技术的应用，由于它的非标准化、开发和维护工作量大，使得其应用不成熟也不普遍。关键行业对数据的可靠性要求又非常之高，使得关键行业用户也不敢冒然选择此种复制技术。</span> </div>
<div>&nbsp;</div>
<div>----DSG RealSync<span style="font-family: 宋体"  ?Times Roman? New Times>属于数据库复制技术，它适用于从工作组级、企业级到数据中心级的复制需求，无论系统采用什么样的服务器平台、什么样的存储平台，只要是</span>ORACLE<span style="font-family: 宋体"  ?Times Roman? New Times>系统之间的复制即可适用。采用</span>DSG RealSync<span style="font-family: 宋体"  ?Times Roman? New Times>复制技术，其目标端数据库在复制过程中处于可用状态，帮助关键行业用户实现生产系统与查询统计报表系统的分离；其源端系统和目标端系统可以采用异构的操作系统平台、存储平台；支持选择性复制，即支持只复制指定的</span>user<span style="font-family: 宋体"  ?Times Roman? New Times>、指定的</span>Table<span style="font-family: 宋体"  ?Times Roman? New Times>、指定的行和列，从而节省存储空间，提高应用灵活性；支持</span>1<span style="font-family: 宋体"  ?Times Roman? New Times>对多，多对</span>1<span style="font-family: 宋体"  ?Times Roman? New Times>的复制结构，即：能够将多个数据库中的数据复制到一个数据库中，能够将一个数据库中的不同数据分发到不同的数据库中；也节约带宽和网络资源，其所需带宽一般在几</span>Mbps,<span style="font-family: 宋体"  ?Times Roman? New Times>几十</span>Mbps<span style="font-family: 宋体"  ?Times Roman? New Times>。</span> </div>
<div>&nbsp;</div>
<div style="line-height: 150%">----<span style="font-family: 宋体"  ?Times Roman? New Times>随着用户容灾意识的逐渐增强，关键行业也提出了建设一套高效、可靠、投资回收比高的灾难备份系统的需求，以确保系统的数据安全和灾难发生时数据的快速恢复。</span> <span>&nbsp;&nbsp;</span></div><img src ="http://www.cppblog.com/tbwshc/aggbug/184604.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/tbwshc/" target="_blank">tbwshc</a> 2012-07-22 13:58 <a href="http://www.cppblog.com/tbwshc/archive/2012/07/22/184604.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Oracle临时表在实际开发中的应用详解</title><link>http://www.cppblog.com/tbwshc/archive/2012/07/08/182184.html</link><dc:creator>tbwshc</dc:creator><author>tbwshc</author><pubDate>Sun, 08 Jul 2012 02:49:00 GMT</pubDate><guid>http://www.cppblog.com/tbwshc/archive/2012/07/08/182184.html</guid><wfw:comment>http://www.cppblog.com/tbwshc/comments/182184.html</wfw:comment><comments>http://www.cppblog.com/tbwshc/archive/2012/07/08/182184.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/tbwshc/comments/commentRss/182184.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/tbwshc/services/trackbacks/182184.html</trackback:ping><description><![CDATA[<p><strong>Oracle临时表</strong>在实际开发中的应用是本文我们主要要介绍的内容，我们知道，SQL Server 在编写查询式的<strong>存储过程</strong>的时候，一直都令我为之赞叹。Create procedure ps_procedure_name as select * from table; Select查询语句可以作为SQL Server存储过程的一部分，直接返回结果集。但在Oracle实现这种形式的存储过程是不合语法的。</p>
<p>为了达到这种目的，我们需要使用Oracle临时表（这是其中一种解决方案）。</p>
<p>Oracle数据库除了可以保存永久表外，还可以建立临时表temporary tables。Oracle临时表分为会话级临时表（ON COMMIT PRESERVE ROWS）和事务级临时表（ON COMMIT DELETE ROWS）。<a href="http://www.tbwshc.com"><span style="color: #000000">tb</span></a>会话级临时表是指临时表中的数据只在会话生命周期之中存在，当用户退出会话结束的时候，Oracle自动清除临时表中数据。</p>
<p>事务级临时表是指临时表中的数据只在事务生命周期中存在。当一个事务结束（commit or rollback），Oracle自动清除临时表中数据。临时表中的数据只对当前Session有效，每个Session都有自己的临时数据，并且不能访问其它Session的临时表中的数据。</p>
<p><strong>//在数据库建立一个临时表：</strong></p>
<p>&nbsp;</p><pre><ol class="dp-xml"><li class="alt"><span>CREATE&nbsp;GLOBAL&nbsp;TEMPORARY&nbsp;TABLE&nbsp;ESPS.ESPS_EMP_RANK_TEMP &nbsp;</span></li><li><span>( &nbsp;</span></li><li class="alt"><span>COM&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;VARCHAR2(20&nbsp;BYTE), &nbsp;</span></li><li><span>EMPNO&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;VARCHAR2(20&nbsp;BYTE), &nbsp;</span></li><li class="alt"><span>EMPNAME&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;VARCHAR2(100&nbsp;BYTE), &nbsp;</span></li><li><span>DEPTNAME&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;VARCHAR2(300&nbsp;BYTE), &nbsp;</span></li><li class="alt"><span>AMOUNT&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NUMBER, &nbsp;</span></li><li><span>APPROVED_AMOUNT&nbsp;&nbsp;NUMBER, &nbsp;</span></li><li class="alt"><span>FOLDING_AMOUNT&nbsp;&nbsp;&nbsp;NUMBER, &nbsp;</span></li><li><span>BENEFIT&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NUMBER, &nbsp;</span></li><li class="alt"><span>EXECUTED_RATE&nbsp;&nbsp;&nbsp;&nbsp;NUMBER, &nbsp;</span></li><li><span>FOLDING_RANK&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NUMBER, &nbsp;</span></li><li class="alt"><span>BENEFIT_RANK&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NUMBER, &nbsp;</span></li><li><span>RANK&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NUMBER, &nbsp;</span></li><li class="alt"><span>TOTAL_RANK&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NUMBER &nbsp;</span></li><li><span>) &nbsp;</span></li><li class="alt"><span>//ON&nbsp;COMMIT&nbsp;PRESERVE&nbsp;ROWS&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;--这里代表的是事务级临时表 &nbsp;</span></li><li><span>ON&nbsp;COMMIT&nbsp;PRESERVE&nbsp;ROWS&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;--这里代表的是会话级临时表&nbsp;</span></li></ol></pre>
<p>&nbsp;</p>
<p>在实际的操作中，我就验证过上面所说的。一开始我使用了事务级临时表，将数据插入到临时表时，使用commit操作，结果临时表的内容清空了。例如是：INSERT INTO ESPS_EMP_RANK_TEMP select * from table；commint；执行这两段SQL后，相当于没有插入数据。</p>
<p>如果我们使用会话级临时表，即使使用了commit，临时表中的内容还是存在的。直到会话断开时，临时表中的内容才真正的清空。所以，在实际的开发过程中，我们因该结合场景，使用不同类型的临时表。</p>
<p>在建议提案系统开发的过程中，我使用了会话级的临时表。将查询的数据插入到临时表中，并且读取临时表的内容，会话断开时，临时表中的内容自动清空。&nbsp;</p>
<p><strong>在C#里面调用的三大步骤：</strong></p>
<p>//C#里面定义的一个String类型的变量，存储一段动态SQL，存储过程为：</p><pre><ol class="dp-xml"><li class="alt"><span>ESPS_EMP_RANK_STATISTIS({0},'{1}') &nbsp;</span></li><li><span>public&nbsp;static&nbsp;string&nbsp;</span><span class="attribute">I_EMP_RANK_STATISTIS</span><span>&nbsp;=&nbsp;</span><span class="attribute-value">"BEGIN&nbsp;ESPS_EMP_RANK_STATISTIS({0},'{1}');&nbsp;END;"</span><span>;&nbsp;</span></li></ol></pre>
<p>&nbsp;</p>
<p>//执行存储过程，把结果集插入到临时表ESPS_EMP_RANK_TEMP</p>
<p>&nbsp;</p><pre><ol class="dp-xml"><li class="alt"><span>WAF.COM.Core.OracleHelper.&nbsp;ExecuteNonQuery(conn,&nbsp;CommandType.Text,&nbsp;string.Format(SqlCollector.I_EMP_RANK_STATISTIS,&nbsp;2,&#8217;2011&#8217;));&nbsp;</span></li></ol></pre>
<p>&nbsp;</p>
<p>//读取临时表中保存的结果集</p>
<p>&nbsp;</p><pre><ol class="dp-xml"><li class="alt"><span>Oracle&nbsp;DataReader&nbsp;</span><span class="attribute">dr</span><span>&nbsp;=&nbsp;</span><span class="attribute-value">WAF</span><span>.COM.Core.OracleHelper.&nbsp;ExecuteReader(&#8220;select&nbsp;*&nbsp;from&nbsp;ESPS_EMP_RANK_TEMP&#8221;)&nbsp;</span></li></ol></pre>
<p>&nbsp;</p>
<p>关于Oracle临时表在实际开发中的应用的相关知识就介绍到这里了，希望本次介绍能够对您有所收获！</p><img src ="http://www.cppblog.com/tbwshc/aggbug/182184.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/tbwshc/" target="_blank">tbwshc</a> 2012-07-08 10:49 <a href="http://www.cppblog.com/tbwshc/archive/2012/07/08/182184.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Oracle临时表和SQL Server临时表的不同点对比</title><link>http://www.cppblog.com/tbwshc/archive/2012/07/08/182183.html</link><dc:creator>tbwshc</dc:creator><author>tbwshc</author><pubDate>Sun, 08 Jul 2012 02:47:00 GMT</pubDate><guid>http://www.cppblog.com/tbwshc/archive/2012/07/08/182183.html</guid><wfw:comment>http://www.cppblog.com/tbwshc/comments/182183.html</wfw:comment><comments>http://www.cppblog.com/tbwshc/archive/2012/07/08/182183.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/tbwshc/comments/commentRss/182183.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/tbwshc/services/trackbacks/182183.html</trackback:ping><description><![CDATA[<p>Oracle数据库创建临时表的过程以及和<strong>SQL Server临时表</strong>的不同点的对比的相关知识是本文我们主要要介绍的内容，接下来就让我们一起来了解一下这部分内容吧，希望能够对您有所帮助。</p>
<p><strong>1.简介</strong></p>
<p>Oracle数据库除了可以保存永久表外，还可以建立临时表temporary tables。这些临时表用来保存一个会话SESSION的数据，或者保存在一个事务中需要的数据。当会话退出或者用户提交commit和回滚rollback事务的时候，临时表的数据自动清空，但是临时表的结构以及元数据还存储在用户的数据字典中。</p>
<p><strong>2.详细介绍</strong></p>
<p><strong>Oracle临时表</strong>分为会话级临时表和事务级临时表。</p>
<p>会话级临时表是指临时表中的数据只在会话生命周期之中存在，当用户退出会话结束的时候，Oracle自动清除临时表中数据。</p>
<p>事务级临时表是指临时表中的数据只在事务生命周期中存在。当一个事务结束（commit or rollback），Oracle自动清除临时表中数据。</p>
<p>临时表中的数据只对当前Session有效，每个Session都有自己的临时数据，并且不能访问其它Session的临时表中的数据。因此，临时表不需要DML锁。</p>
<p>当一个会话结束(用户正常退出 用户不正常退出 ORACLE实例崩溃)或者一个事务结束的时候，Oracle对这个会话的表执行 TRUNCATE 语句清空临时表数据.但不会清空其它会话临时表中的数据.</p>
<p>你可以索引临时表和在临时表基础上建立视图.同样,建立在临时表上的索引也是临时的,也是只对当前会话或者事务有效. 临时表可以拥有触发器.</p>
<p><strong>3.建立临时表</strong></p>
<p>临时表的定义对所有会话SESSION都是可见的,但是表中的数据只对当前的会话或者事务有效.</p>
<p>建立方法：</p><pre><ol class="dp-xml"><li class="alt"><span>1)&nbsp;ON&nbsp;COMMIT&nbsp;DELETE&nbsp;ROWS&nbsp;定义了建立事务级临时表的方法. &nbsp;</span></li><li><span>CREATE&nbsp;GLOBAL&nbsp;TEMPORARY&nbsp;TABLE&nbsp;admin_work_area &nbsp;</span></li><li class="alt"><span>(startdate&nbsp;DATE, &nbsp;</span></li><li><span>enddate&nbsp;DATE, &nbsp;</span></li><li class="alt"><span>class&nbsp;CHAR(20)) &nbsp;</span></li><li><span>ON&nbsp;COMMIT&nbsp;DELETE&nbsp;ROWS; &nbsp;</span></li><li class="alt"><span>EXAMPLE: &nbsp;</span></li><li><span>SQL</span><span class="tag">&gt;</span><span>&nbsp;CREATE&nbsp;GLOBAL&nbsp;TEMPORARY&nbsp;TABLE&nbsp;admin_work_area &nbsp;</span></li><li class="alt"><span>2&nbsp;(startdate&nbsp;DATE, &nbsp;</span></li><li><span>3&nbsp;enddate&nbsp;DATE, &nbsp;</span></li><li class="alt"><span>4&nbsp;class&nbsp;CHAR(20)) &nbsp;</span></li><li><span>5&nbsp;ON&nbsp;COMMIT&nbsp;DELETE&nbsp;ROWS; &nbsp;</span></li><li class="alt"><span>SQL</span><span class="tag">&gt;</span><span>&nbsp;create&nbsp;table&nbsp;permernate(&nbsp;a&nbsp;number); &nbsp;</span></li><li><span>SQL</span><span class="tag">&gt;</span><span>&nbsp;insert&nbsp;into&nbsp;admin_work_area&nbsp;values(sysdate,sysdate,'temperary&nbsp;table'); &nbsp;</span></li><li class="alt"><span>SQL</span><span class="tag">&gt;</span><span>&nbsp;insert&nbsp;into&nbsp;permernate&nbsp;values(1); &nbsp;</span></li><li><span>SQL</span><span class="tag">&gt;</span><span>&nbsp;commit; &nbsp;</span></li><li class="alt"><span>SQL</span><span class="tag">&gt;</span><span>&nbsp;select&nbsp;*&nbsp;from&nbsp;admin_work_area; &nbsp;</span></li><li><span>SQL</span><span class="tag">&gt;</span><span>&nbsp;select&nbsp;*&nbsp;from&nbsp;permernate; &nbsp;</span></li><li class="alt"><span>A &nbsp;</span></li><li><span>1 &nbsp;</span></li><li class="alt"><span>2)ON&nbsp;COMMIT&nbsp;PRESERVE&nbsp;ROWS&nbsp;定义了创建会话级临时表的方法. &nbsp;</span></li><li><span>CREATE&nbsp;GLOBAL&nbsp;TEMPORARY&nbsp;TABLE&nbsp;admin_work_area &nbsp;</span></li><li class="alt"><span>(startdate&nbsp;DATE, &nbsp;</span></li><li><span>enddate&nbsp;DATE, &nbsp;</span></li><li class="alt"><span>class&nbsp;CHAR(20)) &nbsp;</span></li><li><span>ON&nbsp;COMMIT&nbsp;PRESERVE&nbsp;ROWS; &nbsp;</span></li><li class="alt"><span>EXAMPLE:&nbsp;</span></li></ol></pre>
<p>&nbsp;</p>
<p>会话1：</p><pre><ol class="dp-xml"><li class="alt"><span>SQL</span><span class="tag">&gt;</span><span>&nbsp;drop&nbsp;table&nbsp;admin_work_area; &nbsp;</span></li><li><span>SQL</span><span class="tag">&gt;</span><span>&nbsp;CREATE&nbsp;GLOBAL&nbsp;TEMPORARY&nbsp;TABLE&nbsp;admin_work_area &nbsp;</span></li><li class="alt"><span>2&nbsp;(startdate&nbsp;DATE, &nbsp;</span></li><li><span>3&nbsp;enddate&nbsp;DATE, &nbsp;</span></li><li class="alt"><span>4&nbsp;class&nbsp;CHAR(20)) &nbsp;</span></li><li><span>5&nbsp;ON&nbsp;COMMIT&nbsp;PRESERVE&nbsp;ROWS; &nbsp;</span></li><li class="alt"><span>SQL</span><span class="tag">&gt;</span><span>&nbsp;insert&nbsp;into&nbsp;permernate&nbsp;values(2); &nbsp;</span></li><li><span>SQL</span><span class="tag">&gt;</span><span>&nbsp;insert&nbsp;into&nbsp;admin_work_area&nbsp;values(sysdate,sysdate,'session&nbsp;temperary'); &nbsp;</span></li><li class="alt"><span>SQL</span><span class="tag">&gt;</span><span>&nbsp;commit; &nbsp;</span></li><li><span>SQL</span><span class="tag">&gt;</span><span>&nbsp;select&nbsp;*&nbsp;from&nbsp;permernate; &nbsp;</span></li><li class="alt"><span>A &nbsp;</span></li><li><span>---------- &nbsp;</span></li><li class="alt"><span>1 &nbsp;</span></li><li><span>2 &nbsp;</span></li><li class="alt"><span>SQL</span><span class="tag">&gt;</span><span>&nbsp;select&nbsp;*&nbsp;from&nbsp;admin_work_area; &nbsp;</span></li><li><span>STARTDATE&nbsp;ENDDATE&nbsp;CLASS &nbsp;</span></li><li class="alt"><span>----------&nbsp;----------&nbsp;-------------------- &nbsp;</span></li><li><span>17-1??&nbsp;-03&nbsp;17-1??&nbsp;-03&nbsp;session&nbsp;temperary&nbsp;</span></li></ol></pre>
<p>&nbsp;</p>
<p>会话2：</p><pre><ol class="dp-xml"><li class="alt"><span>SQL</span><span class="tag">&gt;</span><span>&nbsp;select&nbsp;*&nbsp;from&nbsp;permernate; &nbsp;</span></li><li><span>A &nbsp;</span></li><li class="alt"><span>---------- &nbsp;</span></li><li><span>1 &nbsp;</span></li><li class="alt"><span>2 &nbsp;</span></li><li><span>SQL</span><span class="tag">&gt;</span><span>&nbsp;select&nbsp;*&nbsp;from&nbsp;admin_work_area; &nbsp;</span></li><li class="alt"><span>未选择行.&nbsp;</span></li></ol></pre>
<p>&nbsp;</p>
<p>会话2看不见会话1中临时表的数据。</p>
<p><strong>4.Oracle临时表和SQL Server临时表异同</strong></p>
<p>SQL Server也可以创建临时表。临时表与永久表相似，但临时表存储在tempdb中，当不再使用时会自动删除。</p>
<p>有本地和全局两种类型的临时表，二者在名称、可见性和可用性上均不相同。本地临时表的名称以单个数字符号 (#) 打头；它们仅对当前的用户连接是可见的；当用户从 Microsoft SQL Server实例断开连接时被删除。全局临时表的名称以数学符号 (##) 打头，创建后对任何用户都是可见的，当所有引用该表的用户从 SQL Server 断开连接时被删除。</p>
<p>SQL 语句使用 CREATE TABLE 语句中为 table_name 指定的名称引用临时表：</p><pre><ol class="dp-xml"><li class="alt"><span>CREATE&nbsp;TABLE&nbsp;#MyTempTable&nbsp;(cola&nbsp;INT&nbsp;PRIMARY&nbsp;KEY) &nbsp;</span></li><li><span>INSERT&nbsp;INTO&nbsp;#MyTempTable&nbsp;VALUES&nbsp;(1)&nbsp;</span></li></ol></pre>
<p>&nbsp;</p>
<p>如果本地临时表由存储过程创建或由多个用户同时执行的应用程序创建，则 SQL Server 必须能够区分由不同用户创建的表。为此，SQL Server 在内部为每个本地临时表的表名追加一个数字后缀。存储在 tempdb 数据库的 sysobjects 表中的临时表，其全名由 CREATE TABLE 语句中指定的表名和系统生成的数字后缀组成。为了允许追加后缀，为本地临时表指定的表名 table_name 不能超过116 个字符。</p>
<p>除非使用 DROP TABLE 语句显式除去临时表，否则临时表将在退出其作用域时由系统自动除去：</p>
<p>当存储过程完成时，将自动除去在存储过程中创建的本地临时表。由创建表的存储过程执行的所有嵌套存储过程都可以引用此表。但调用创建此表的存储过程的进程无法引用此表。</p>
<p>所有其它本地临时表在当前会话结束时自动除去。</p>
<p>全局临时表在创建此表的会话结束且其它任务停止对其引用时自动除去。任务与表之间的关联只在单个 Transact-SQL 语句的生存周期内保持。换言之，当创建全局临时表的会话结束时，最后一条引用此表的Transact-SQL语句完成后，将自动除去此表。</p>
<p>例如，如果创建名为 employees 的表，则任何人只要在数据库中有使用该表的安全权限就可以使用该表，除非它已删除。如果创建名为 #employees 的本地临时表，只有您能对该表执行操作且在断开连接时该表删除。如果创建名为 ##employees 的全局临时表，数据库中的任何用户均可对该表执行操作。如果该表在您创建后没有其他用户使用，则当您断开连接时该表删除。如果该表在您创建后有其他用户使用，则 SQL Server在所有用户断开连接后删除该表。</p>
<p>在存储过程或触发器中创建的本地临时表与在调用存储过程或触发器之前创建的同名临时表不同。如果查询引用临时表，而同时有两个同名的临时表，则不定义针对哪个表解析该查询。<a href="http://www.tbwshc.com"><span style="color: #000000">tb</span></a>嵌套存储过程同样可以创建与调用它的存储过程所创建的临时表同名的临时表。嵌套存储过程中对表名的所有引用都被解释为是针对该嵌套过程所创建的表，例如：</p>
<p>&nbsp;</p><pre><ol class="dp-xml"><li class="alt"><span>CREATE&nbsp;PROCEDURE&nbsp;Test2 &nbsp;</span></li><li><span>AS &nbsp;</span></li><li class="alt"><span>CREATE&nbsp;TABLE&nbsp;#t(x&nbsp;INT&nbsp;PRIMARY&nbsp;KEY) &nbsp;</span></li><li><span>INSERT&nbsp;INTO&nbsp;#t&nbsp;VALUES&nbsp;(2) &nbsp;</span></li><li class="alt"><span>SELECT&nbsp;</span><span class="attribute">Test2Col</span><span>&nbsp;=&nbsp;</span><span class="attribute-value">x</span><span>&nbsp;FROM&nbsp;#t &nbsp;</span></li><li><span>GO &nbsp;</span></li><li class="alt"><span>CREATE&nbsp;PROCEDURE&nbsp;Test1 &nbsp;</span></li><li><span>AS &nbsp;</span></li><li class="alt"><span>CREATE&nbsp;TABLE&nbsp;#t(x&nbsp;INT&nbsp;PRIMARY&nbsp;KEY) &nbsp;</span></li><li><span>INSERT&nbsp;INTO&nbsp;#t&nbsp;VALUES&nbsp;(1) &nbsp;</span></li><li class="alt"><span>SELECT&nbsp;</span><span class="attribute">Test1Col</span><span>&nbsp;=&nbsp;</span><span class="attribute-value">x</span><span>&nbsp;FROM&nbsp;#t &nbsp;</span></li><li><span>EXEC&nbsp;Test2 &nbsp;</span></li><li class="alt"><span>GO &nbsp;</span></li><li><span>CREATE&nbsp;TABLE&nbsp;#t(x&nbsp;INT&nbsp;PRIMARY&nbsp;KEY) &nbsp;</span></li><li class="alt"><span>INSERT&nbsp;INTO&nbsp;#t&nbsp;VALUES&nbsp;(99) &nbsp;</span></li><li><span>GO &nbsp;</span></li><li class="alt"><span>EXEC&nbsp;Test1 &nbsp;</span></li><li><span>GO&nbsp;&nbsp;</span></li></ol></pre>
<p>&nbsp;</p>
<p>下面是结果集：</p><pre><ol class="dp-xml"><li class="alt"><span>(1&nbsp;row(s)&nbsp;affected) &nbsp;</span></li><li><span>Test1Col&nbsp; &nbsp;</span></li><li class="alt"><span>-----------&nbsp; &nbsp;</span></li><li><span>1&nbsp; &nbsp;</span></li><li class="alt"><span>(1&nbsp;row(s)&nbsp;affected) &nbsp;</span></li><li><span>Test2Col&nbsp; &nbsp;</span></li><li class="alt"><span>-----------&nbsp; &nbsp;</span></li><li><span>2&nbsp;</span></li></ol></pre>
<p>&nbsp;</p>
<p>当创建本地或全局临时表时，CREATE TABLE 语法支持除 FOREIGN KEY 约束以外的其它所有约束定义。如果在临时表中指定 FOREIGN KEY 约束，该语句将返回警告信息，指出此约束已被忽略，表仍会创建，但不具有 FOREIGN KEY 约束。在 FOREIGN KEY 约束中不能引用临时表。</p>
<p>考虑使用表变量而不使用临时表。当需要在临时表上显式地创建索引时，或多个存储过程或函数需要使用表值时，临时表很有用。通常，表变量提供更有效的查询处理。</p>
<p><strong>和Oracle的不同点：</strong></p>
<p>1. SQL Server临时表是一种&#8221;内存表&#8221;,<a href="http://www.tbwshc.com"><span style="color: #000000">tb</span></a>表是存储在内存中的.ORACLE临时表除非执行DROP TABLE,否则表定义会保留在数据字典中。</p>
<p>2. SQL Server临时表不存在类似ORACLE临时表事务级别上的功能。</p>
<p>3.SQL Server本地临时表(#) 与 ORACLE的会话级别临时表类似,但是在会话退出的时候,ORACLE不会删除表。</p>
<p>4.SQL Server的全局临时表(##) 是指多个连接共享同一片内存.当没有指针引用该内存区域时,SQL Server自动释放全局临时表。</p>
<p>5.由于Oracle不是一种内存中的数据库. 所以如果Oracle类似SQL Server 频繁的对临时表进行建立和删除,必定会影响性能.所以Oracle会保留临时表的定义直到用户DROP TABLE。</p>
<p>6.在Oracle中,如果需要多个用户共享一个表(类似SQL Server的全局临时表##).则可以利用永久表,并且在表中添加一些可以唯一标识用户的列.利用触发器和视图.当用户退出的时候,根据该登陆用户的唯一信息删除相应的表中的数据. 这种方法给Oracle带来了一定量的负载。</p>
<p>&nbsp;</p>
<p>关于Oracle临时表和SQL Server临时表的不同点对比的相关知识就介绍到这里了，希望本次的介绍能够对您有所收获！</p><img src ="http://www.cppblog.com/tbwshc/aggbug/182183.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/tbwshc/" target="_blank">tbwshc</a> 2012-07-08 10:47 <a href="http://www.cppblog.com/tbwshc/archive/2012/07/08/182183.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>详解Oracle临时表的几种用法及意义</title><link>http://www.cppblog.com/tbwshc/archive/2012/07/07/182066.html</link><dc:creator>tbwshc</dc:creator><author>tbwshc</author><pubDate>Sat, 07 Jul 2012 05:26:00 GMT</pubDate><guid>http://www.cppblog.com/tbwshc/archive/2012/07/07/182066.html</guid><wfw:comment>http://www.cppblog.com/tbwshc/comments/182066.html</wfw:comment><comments>http://www.cppblog.com/tbwshc/archive/2012/07/07/182066.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/tbwshc/comments/commentRss/182066.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/tbwshc/services/trackbacks/182066.html</trackback:ping><description><![CDATA[<p>Oracle临时表可以说是提高数据库处理性能的好方法，在没有必要存储时，只存储在Oracle临时表空间中。希望本文能对大家有所帮助。</p>
<p>1 、前言</p>
<p>&nbsp;</p>
<p>Oracle Logo</p>
<p>目前所有使用 Oracle 作为数据库支撑平台的应用，大部分数据量比较庞大的系统，即表的数据量一般情况下都是在百万级以上的数据量。</p>
<p>当然在 Oracle 中创建分区是一种不错的选择，但是当你发现你的应用有多张表关联的时候，并且这些表大部分都是比较庞大，而你关联的时候发现其中的某一张或者某几张表关联之后得到的结果集非常小并且查询得到这个结果集的速度非常快，那么这个时候我考虑在 Oracle 中创建&#8220;临时表&#8221;。</p>
<p>我对临时表的理解：在 Oracle 中创建一张表，这个表不用于其他的什么功能，主要用于自己的软件系统一些特有功能才用的，而当你用完之后表中的数据就没用了。 Oracle 的临时表创建之后基本不占用表空间，如果你没有指定临时表(包括临时表的索引)存放的表空的时候，你插入到临时表的数据是存放在 ORACLE 系统的临时表空间中( TEMP )。</p>
<p>2 、临时表的创建</p>
<p>创建Oracle 临时表，可以有两种类型的临时表：</p>
<p>会话级的临时表</p>
<p>事务级的临时表 。</p>
<p>1) 会话级的临时表因为这这个临时表中的数据和你的当前会话有关系，当你当前SESSION 不退出的情况下，临时表中的数据就还存在，而当你退出当前SESSION 的时候，临时表中的数据就全部没有了，当然这个时候你如果以另外一个SESSION 登陆的时候是看不到另外一个SESSION 中插入到临时表中的数据的。即两个不同的SESSION 所插入的数据是互不相干的。当某一个SESSION 退出之后临时表中的数据就被截断(truncate table ，即数据清空)了。会话级的临时表创建方法：</p>
<p><br />Create Global Temporary Table Table_Name&nbsp; (Col1 Type1,Col2 Type2...) On Commit Preserve Rows ; <br />举例：</p>
<p><br />create global temporary table Student&nbsp; (Stu_id Number(5),&nbsp; Class_id Number(5),&nbsp; Stu_Name Varchar2(8),&nbsp; Stu_Memo varchar2(200)) on Commit Preserve Rows ; <br />2) 事务级临时表是指该临时表与事务相关，当进行事务提交或者事务回滚的时候，临时表中的数据将自行被截断，其他的内容和会话级的临时表的一致(包括退出SESSION 的时候，事务级的临时表也会被自动截断)。事务级临时表的创建方法：</p>
<p><br />Create Global Temporary Table Table_Name&nbsp; (Col1 Type1,Col2 Type2...) On Commit Delete Rows ; <br />举例：</p>
<p>create global temporary table Classes&nbsp; (Class_id Number(5),&nbsp; Class_Name Varchar2(8),&nbsp; Class_Memo varchar2(200)) on Commit delete Rows ; 3) 两中类型临时表的区别</p>
<p>会话级临时表采用 on commit preserve rows ;而事务级则采用 on commit delete rows ;用法上，会话级别只有当会话结束临时表中的数据才会被截断，而且事务级临时表则不管是 commit 、 rollback 或者是会话结束，<a href="http://www.tbwshc.com"><span style="color: #000000">tb</span></a>临时表中的数据都将被截断</p>
<p>4 )什么时候使用临时表</p>
<p>1 )、当某一个 SQL 语句关联的表在 2 张及以上，并且和一些小表关联。可以采用将大表进行分拆并且得到比较小的结果集合存放在临时表中</p>
<p>2 )、程序执行过程中可能需要存放一些临时的数据，这些数据在整个程序的会话过程中都需要用的等等。</p>
<p>3 . 例子：略</p>
<p>4 .临时表的不足之处</p>
<p>1 )不支持 lob 对象，这也许是设计者基于运行效率的考虑，但实际应用中确实需要此功能时就无法使用临时表了。</p>
<p>2 )不支持主外键关系</p>
<p>所以，由于以上原因，我们可以自己创建临时表，以弥补 oracle 临时表的不足之处</p>
<p>上面的都是本人经过测试的，但下面是在网上搜索到的方法，本人具体没有测试过，不过觉得可行性很强，有时间测试下</p>
<p>创建方法：</p>
<p>1 、以常规表的形式创建临时数据表的表结构，但要在每一个表的主键中加入一个 SessionID 列以区分不同的会话。(可以有 lob 列和主外键)</p>
<p>2 、写一个用户注销触发器，在用户结束会话的时候删除本次会话所插入的所有记录 (SessionID 等于本次会话 ID 的记录 ) 。</p>
<p>3 、程序写入数据时，要顺便将当前的会话 ID(SessionID) 写入表中。</p>
<p>4 、程序读取数据时，只读取与当前会话 ID 相同的记录即可。</p>
<p>功能增强的扩展设计：</p>
<p>1 、可以在数据表上建立一个视图，视图对记录的筛选条件就是当前会话的SessionID 。</p>
<p>2 、数据表中的SessionID 列可以通过Trigger 实现，以实现对应用层的透明性。</p>
<p>3 、高级用户可以访问全局数据，以实现更加复杂的功能。</p>
<p>扩展临时表的优点：</p>
<p>1 、实现了与Oracle 的基于会话的临时表相同的功能。</p>
<p>2 、支持SDO_GEOMETRY 等lob 数据类型。</p>
<p>3 、支持表间的主外键连接，且主外键连接也是基于会话的。</p>
<p>4 、高级用户可以访问全局数据，以实现更加复杂的功能</p>
<p>&nbsp;</p><img src ="http://www.cppblog.com/tbwshc/aggbug/182066.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/tbwshc/" target="_blank">tbwshc</a> 2012-07-07 13:26 <a href="http://www.cppblog.com/tbwshc/archive/2012/07/07/182066.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ORACLE联机日志文件丢失或损坏的处理方法</title><link>http://www.cppblog.com/tbwshc/archive/2012/07/07/182065.html</link><dc:creator>tbwshc</dc:creator><author>tbwshc</author><pubDate>Sat, 07 Jul 2012 05:24:00 GMT</pubDate><guid>http://www.cppblog.com/tbwshc/archive/2012/07/07/182065.html</guid><wfw:comment>http://www.cppblog.com/tbwshc/comments/182065.html</wfw:comment><comments>http://www.cppblog.com/tbwshc/archive/2012/07/07/182065.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/tbwshc/comments/commentRss/182065.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/tbwshc/services/trackbacks/182065.html</trackback:ping><description><![CDATA[经验总结： 
<p>联机日志分为当前联机日志和非当前联机日志，非当前联机日志的损坏是比较简单的，一般通过clear命令就可以解决问题。</p>
<p>损坏非当前联机日志：<br />1、启动数据库，遇到ORA-00312 or ORA-00313错误，如:<br />ORA-00313: open failed for members of log group 4 of <a href="http://www.tbwshc.com"><span style="color: #000000">tb</span></a>hread 1<br />ORA-00312: online log 3 thread 1: '/opt/oracle/db04/oradata/ORCL/redo03.log'<br />从这里我们知道日志组1的数据文件损坏或丢失了<br />从报警文件可以看到更详细的信息<br />2、查看V$log视图:<br />SQL&gt; select group#,sequence#,archived,status from v$log;</p>
<p>GROUP# SEQUENCE# ARC STATUS</p>
<p>---------- ---------- --- ----------------</p>
<p>1 54 YES INACTIVE</p>
<p>2 55 NO CURRENT</p>
<p>3 53 YES INACTIVE</p>
<p>可以知道，该组是非当前状态，而且已经归档。<br />3、用CLEAR命令重建该日志文件<br />SQL&gt;alter database clear logfile group 3;<br />如果是该日志组还没有归档，则需要用<br />SQL&gt;alter database clear unarchived logfile group 3;<br />4、打开数据库，重新备份数据库<br />SQL&gt;alter database open;<br />说明：<br />1)、如果损坏的是非当前的联机日志文件，一般只需要clear就可以重建该日志文件，但是如果该数据库处于归档状态但该日志还没有归档，就需要强行clear。<br />2)、建议clear，特别是强行clear后作一次数据库的全备份。<br />3)、此方法适用于归档与非归档数据库。</p>
<p>损坏当前联机日志：</p>
<p>归档模式下当前日志的损坏有两种情况，<br />一、是数据库是正常关闭，日志文件中没有未决的事务需要实例恢复，当前日志组的损坏就可以直接用alter database clear unarchived logfile group n来重建。<br />二、是日志组中有活动的事务，数据库需要媒体恢复，日志组需要用来同步，有两种补救办法<br />A. 最好的办法就是通过不完全恢复，可以保证数据库的一致性，但是这种办法要求在归档方式下，并且有可用的备份<br />B. 通过强制性恢复，但是可能导致数据库不一致。<br />下面分别用来说明这两种恢复方法<br />5.1.2.1 通过备份来恢复<br />1、打开数据库，会遇到一个类似的错误<br />ORA-00313: open failed for members of log group 1 of thread 1<br />ORA-00312: online log 1 thread 1: 'D:ORACLEORADATATESTREDO01.LOG'<br />ORA-27041: unable to open file<br />OSD-04002: unable to open file<br />O/S-Error: (OS 2) 系统找不到指定的文件</p>
<p>2、查看V$log，发现是当前日志<br />SQL&gt; select group#,sequence#,archived,status from v$log;</p>
<p>GROUP# SEQUENCE# ARCHIVED STATUS<br />---------- ---------- -------- ----------------<br />1 1 NO CURRENT<br />2 2 YES INACTIVE<br />3 3 YES INACTIVE</p>
<p>3、发现clear不成功<br />SQL&gt; alter database clear unarchived logfile group 1;<br />alter database clear unarchived logfile group 1<br />*<br />ERROR at line 1:<br />ORA-01624: log 1 needed for crash recovery of thread 1<br />ORA-00312: online log 1 thread 1: 'D:ORACLEORADATATESTREDO01.LOG'</p>
<p>4、拷贝有效的数据库的全备份，并不完全恢复数据库<br />可以采用获取最近的SCN的办法用until scn恢复或用until cnacel恢复<br />recover database until cancel<br />先选择auto，尽量恢复可以利用的归档日志，然后重新<br />recover database until cancel<br />这次输入cancel，完成不完全恢复，也就是说恢复两次。<br />如：<br />SQL&gt; recover database until cancel;<br />Auto<br />&#8230;&#8230;<br />SQL&gt; recover database until cancel;<br />Cancel;<br />5、利用alter database open resetlogs打开数据库<br />说明：<br />1、这种办法恢复的数据库是一致的不完全恢复，会丢失当前联机日志中的事务数据<br />2、这种方法适合于归档数据库并且有可用的数据库全备份。<br />3、恢复成功之后，记得再做一次数据库的全备份。<br />4、建议联机日志文件一定要实现镜相在不同的磁盘上，避免这种情况的发生，因为任何数据的丢失对于生产来说都是不容许的。</p>
<p>如果没有备份，进行强制性恢复<br />1、打开数据库，会遇到一个类似的错误<br />ORA-00313: open failed for members of log group 1 of thread 1<br />ORA-00312: online log 1 thread 1: 'D:ORACLEORADATATESTREDO01.LOG'<br />ORA-27041: unable to open file<br />OSD-04002: unable to open file<br />O/S-Error: (OS 2) 系统找不到指定的文件</p>
<p>2、查看V$log，发现是当前日志<br />SQL&gt; select group#,sequence#,archived,status from v$log;</p>
<p>GROUP# SEQUENCE# ARCHIVED STATUS<br />---------- ---------- -------- ----------------<br />1 1 NO CURRENT<br />2 2 YES INACTIVE<br />3 3 YES INACTIVE</p>
<p>3、发现clear不成功<br />SQL&gt; alter database clear unarchived logfile group 1;<br />alter database clear unarchived logfile group 1<br />*<br />ERROR at line 1:<br />ORA-01624: log 1 needed for crash recovery of thread 1<br />ORA-00312: online log 1 thread 1: 'D:ORACLEORADATATESTREDO01.LOG'</p>
<p>4、把数据库down掉<br />SQL&gt;shutdown immediate</p>
<p>5、在init&lt;sid&gt;.ora中加入如下参数<br />_allow_resetlogs_corruption=TRUE</p>
<p>6、重新启动数据库,利用until cancel恢复<br />SQL&gt;recover database until cancel; <br />Cancel<br />如果出错，不再理会，发出 <br />SQL&gt;alter database open resetlogs;</p>
<p>7、数据库被打开后，马上执行一个full export</p>
<p>8、shutdown数据库,去掉_all_resetlogs_corrupt参数 </p>
<p>9、重建库</p>
<p>10、import并完成恢复</p>
<p>11、建议执行一下ANALYZE TABLE ...VALIDATE STRUCTURE CASCADE;<br />说明：<br />1、该恢复方法是没有办法之后的恢复方法，一般情况下建议不要采用，因为该方法可能导致数据库的不一致<br />2、该方法也丢失数据，但是丢失的数据没有上一种方法的数据多，主要是未写入数据文件的已提交或未提交数据。<br />3、建议成功后严格执行以上的7到11步，完成数据库的检查与分析<br />4、全部完成后做一次数据库的全备份<br />5、建议联机日志文件一定要实现镜相在不同的磁盘上，避免这种情况的发生，因为任何数据的丢失对于生产来说都是不容许的。</p><img src ="http://www.cppblog.com/tbwshc/aggbug/182065.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/tbwshc/" target="_blank">tbwshc</a> 2012-07-07 13:24 <a href="http://www.cppblog.com/tbwshc/archive/2012/07/07/182065.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>