﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-人生就是努力!-文章分类-oracle</title><link>http://www.blogjava.net/jesenblog/category/30195.html</link><description /><language>zh-cn</language><lastBuildDate>Mon, 31 Mar 2008 07:49:49 GMT</lastBuildDate><pubDate>Mon, 31 Mar 2008 07:49:49 GMT</pubDate><ttl>60</ttl><item><title>如何从表空间中“删除”数据文件</title><link>http://www.blogjava.net/jesenblog/articles/189573.html</link><dc:creator>白露</dc:creator><author>白露</author><pubDate>Sun, 30 Mar 2008 02:17:00 GMT</pubDate><guid>http://www.blogjava.net/jesenblog/articles/189573.html</guid><wfw:comment>http://www.blogjava.net/jesenblog/comments/189573.html</wfw:comment><comments>http://www.blogjava.net/jesenblog/articles/189573.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jesenblog/comments/commentRss/189573.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jesenblog/services/trackbacks/189573.html</trackback:ping><description><![CDATA[<p style="margin: 0cm 0cm 0pt; text-indent: 17.95pt"><span style="font-family: 宋体">如果你的表空间有多个数据文件，而你不需要表空间中的内容，或者你可以很容易重新生产表空间的内容，你可以使用</span>DROP TABLESPACE &lt;tablespace name&gt; INCLUDING CONTENTS;<span style="font-family: 宋体">命令来从</span>Oracle<span style="font-family: 宋体">数据字典删除表空间、数据文件和表空间的内容。</span>Oracle<span style="font-family: 宋体">不会再访问该表空间中的任何内容。然后重新创建表空间并重新导入数据。</span></p>
<p style="margin: 0cm 0cm 0pt; text-indent: 17.95pt"><span style="font-family: 宋体">如果你的表空间有多个数据文件，而你还需保留该表空间中的其它数据文件中的内容，则你必须首先</span>export<span style="font-family: 宋体">出该表空间中的所有内容。为了确定表空间中包含那些内容，运行：</span></p>
<p style="margin: 0cm 0cm 0pt; text-indent: 17.95pt">select owner,segment_name,segment_type </p>
<p style="margin: 0cm 0cm 0pt; text-indent: 17.95pt">from dba_segments </p>
<p style="margin: 0cm 0cm 0pt; text-indent: 17.95pt">where tablespace_name='&lt;name of tablespace&gt;'</p>
<p style="margin: 0cm 0cm 0pt; text-indent: 17.95pt">export<span style="font-family: 宋体">出你想保留的内容。如果</span>export<span style="font-family: 宋体">结束，你可以使用</span>DROP TABLESPACE tablespace INCLUDING CONTENTS. <span style="font-family: 宋体">，</span> <span style="font-family: 宋体">这样永久删除表空间的内容，使用操作系统命令物理删除数据文件，按所需数据文件重新创建表空间，把数据</span>import<span style="font-family: 宋体">至表空间。</span></p>
<p style="margin: 0cm 0cm 0pt; text-indent: 17.95pt"><span style="font-family: 宋体">注意：</span></p>
<p style="margin: 0cm 0cm 0pt; text-indent: 17.95pt">ALTER DATABASE DATAFILE &lt;datafile name&gt; OFFLINE DROP<span style="font-family: 宋体">命令不能允许你删除数据文件，它的目的是脱机该数据文件以删除表空间。如果在归档模式下，使用</span>ALTER DATABASE DATAFILE &lt;datafile name&gt; OFFLINE DROP<span style="font-family: 宋体">来代替</span>OFFLINE DROP<span style="font-family: 宋体">。一旦数据文件脱机，</span>Oracle<span style="font-family: 宋体">不会再访问该数据文件的内容，但它仍然是表空间的一部分。这个数据文件在控制文件中标记</span>OFFLINE<span style="font-family: 宋体">，在数据库启动时不会对它与控制文件进行</span>SCN<span style="font-family: 宋体">的比较。在控制文件中保留这个数据文件的入口是方便以后的恢复。</span></p>
<p style="margin: 0cm 0cm 0pt; text-indent: 17.95pt"><span style="font-family: 宋体">如果你不想按照上述方法来删除表空间，还有其它一些解决方法。</span></p>
<p style="margin: 0cm 0cm 0pt 38.95pt; text-indent: -21pt; tab-stops: list 38.95pt">1.<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="font-family: 宋体">如果你想删除数据文件的原因是因为分配了不合适的文件大小，你可以考虑</span>RESIZE<span style="font-family: 宋体">命令。</span></p>
<p style="margin: 0cm 0cm 0pt 38.95pt; text-indent: -21pt; tab-stops: list 38.95pt">2.<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="font-family: 宋体">如果你不小心增加了一个数据文件，而这个文件还没有分配空间，你可以使用</span></p>
<p style="margin: 0cm 0cm 0pt; text-indent: 17.95pt">ALTER DATABASE DATAFILE &lt;filename&gt; RESIZE;<span style="font-family: 宋体">命令使其小于</span>5个 Oracle<span style="font-family: 宋体">块大小，如果数据文件的大小小于这个，</span>Oracle<span style="font-family: 宋体">将不会进行扩展数据文件。在以后，</span>Oracle<span style="font-family: 宋体">可以重建的时候来剔除这个不正确的文件。</span></p>
<img src ="http://www.blogjava.net/jesenblog/aggbug/189573.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jesenblog/" target="_blank">白露</a> 2008-03-30 10:17 <a href="http://www.blogjava.net/jesenblog/articles/189573.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>数据库范式1NF 2NF 3NF BCNF(实例） </title><link>http://www.blogjava.net/jesenblog/articles/188262.html</link><dc:creator>白露</dc:creator><author>白露</author><pubDate>Mon, 24 Mar 2008 07:34:00 GMT</pubDate><guid>http://www.blogjava.net/jesenblog/articles/188262.html</guid><wfw:comment>http://www.blogjava.net/jesenblog/comments/188262.html</wfw:comment><comments>http://www.blogjava.net/jesenblog/articles/188262.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jesenblog/comments/commentRss/188262.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jesenblog/services/trackbacks/188262.html</trackback:ping><description><![CDATA[<div class="cnt" dir="ltr" _extended="true"><span style="color: red" _extended="true">设计范式</span>（<font face="Verdana" _extended="true"><font color="#800080" _extended="true">范式</font>,数据库设计范式,数据库的设计范式）是符合某一种级别的关系模式的集合。构造数据库必须遵循一定的规则。在关系数据库中，这种规则就是范式。关系数据库中的关系必须满足一定的要求，即满足不同的范式。目前关系数据库有六种范式：第一范式（1NF）、第二范式（2NF）、第三范式（3NF）、第四范式（4NF）、第五范式（5NF）和第六范式（6NF）。满足最低要求的范式是第一范式（1NF）。在第一范式的基础上进一步满足更多要求的称为第二范式（2NF），其余范式以次类推。一般说来，数据库只需满足第三范式（3NF）就行了。下面我们举例介绍第一范式（1NF）、第二范式（2NF）和第三范式（3NF）。</font></div>
<p class="cnt" _extended="true"><font face="Verdana" _extended="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 在创建一个数据库的过程中，范化是将其转化为一些表的过程，这种方法可以使从数据库得到的结果更加明确。这样可能使数据库产生重复数据，从而导致创建多余的表。范化是在识别数据库中的数据元素、关系，以及定义所需的表和各表中的项目这些初始工作之后的一个细化的过程。</font></p>
<p class="cnt" _extended="true"><font face="Verdana" _extended="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 下面是范化的一个例子 Customer Item purchased Purchase price Thomas Shirt $40 Maria Tennis shoes $35 Evelyn Shirt $40 Pajaro Trousers $25</font></p>
<p class="cnt" _extended="true"><font face="Verdana" _extended="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 如果上面这个表用于保存物品的价格，而你想要删除其中的一个顾客，这时你就必须同时删除一个价格。范化就是要解决这个问题，你可以将这个表化为两个表，一个用于存储每个顾客和他所买物品的信息，另一个用于存储每件产品和其价格的信息，这样对其中一个表做添加或删除操作就不会影响另一个表。<br _extended="true" />
<br _extended="true" />
<strong _extended="true"><u _extended="true">关系数据库的几种设计范式介绍</u></strong></font></p>
<p class="cnt" _extended="true"><font face="Verdana" _extended="true"><br _extended="true" />
<strong _extended="true">1 第一范式（1NF）</strong></font></p>
<p class="cnt" _extended="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 在任何一个关系数据库中，第一范式（1NF）是对关系模式的基本要求，不满足第一范式（1NF）的数据库就不是关系数据库。</p>
<p class="cnt" _extended="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 所谓第一范式（1NF）是指数据库表的每一列都是不可分割的基本数据项，同一列中不能有多个值，即实体中的某个属性不能有多个值或者不能有重复的属性。如果出现重复的属性，就可能需要定义一个新的实体，新的实体由重复的属性构成，新实体与原实体之间为一对多关系。在第一范式（1NF）中表的每一行只包含一个实例的信息。例如，对于图3-2 中的员工信息表，不能将员工信息都放在一列中显示，也不能将其中的两列或多列在一列中显示；员工信息表的每一行只表示一个员工的信息，一个员工的信息在表中只出现一次。简而言之，第一范式就是无重复的列。</p>
<p class="cnt" _extended="true"><strong _extended="true">2 第二范式（2NF）</strong></p>
<p class="cnt" _extended="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 第二范式（2NF）是在第一范式（1NF）的基础上建立起来的，即满足第二范式（2NF）必须先满足第一范式（1NF）。第二范式（2NF）要求数据库表中的每个实例或行必须可以被惟一地区分。为实现区分通常需要为表加上一个列，以存储各个实例的惟一标识。如图3-2 员工信息表中加上了员工编号（emp_id）列，因为每个员工的员工编号是惟一的，因此每个员工可以被惟一区分。这个惟一属性列被称为主关键字或主键、主码。</p>
<p class="cnt" _extended="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 第二范式（2NF）要求实体的属性完全依赖于主关键字。所谓完全依赖是指不能存在仅依赖主关键字一部分的属性，如果存在，那么这个属性和主关键字的这一部分应该分离出来形成一个新的实体，新实体与原实体之间是一对多的关系。为实现区分通常需要为表加上一个列，以存储各个实例的惟一标识。简而言之，第二范式就是非主属性非部分依赖于主关键字。</p>
<p class="cnt" _extended="true"><strong _extended="true">3 第三范式（3NF）</strong></p>
<p class="cnt" _extended="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 满足第三范式（3NF）必须先满足第二范式（2NF）。简而言之，第三范式（3NF）要求一个数据库表中不包含已在其它表中已包含的非主关键字信息。例如，存在一个部门信息表，其中每个部门有部门编号（dept_id）、部门名称、部门简介等信息。那么在图3-2的员工信息表中列出部门编号后就不能再将部门名称、部门简介等与部门有关的信息再加入员工信息表中。如果不存在部门信息表，则根据第三范式（3NF）也应该构建它，否则就会有大量的数据冗余。简而言之，第三范式就是属性不依赖于其它非主属性。</p>
<p class="cnt" _extended="true"><font face="Verdana" _extended="true"><strong _extended="true"><u _extended="true">数据库设计三大范式应用实例剖析</u></strong></font></p>
<p class="cnt" _extended="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 数据库的设计范式是数据库设计所需要满足的规范，满足这些规范的数据库是简洁的、结构明晰的，同时，不会发生插入（insert）、删除（delete）和更新（update）操作异常。反之则是乱七八糟，不仅给数据库的编程人员制造麻烦，而且面目可憎，可能存储了大量不需要的冗余信息。<br _extended="true" />
<br _extended="true" />
　　设计范式是不是很难懂呢？非也，大学教材上给我们一堆数学公式我们当然看不懂，也记不住。所以我们很多人就根本不按照范式来设计数据库。<br _extended="true" />
<br _extended="true" />
　　实质上，设计范式用很形象、很简洁的话语就能说清楚，道明白。本文将对范式进行通俗地说明，并以笔者曾经设计的一个简单论坛的数据库为例来讲解怎样将这些范式应用于实际工程。<br _extended="true" />
<br _extended="true" />
<strong _extended="true">　　 范式说明</strong><br _extended="true" />
<br _extended="true" />
　　第一范式（1NF）：数据库表中的字段都是单一属性的，不可再分。这个单一属性由基本类型构成，包括整型、实数、字符型、逻辑型、日期型等。<br _extended="true" />
<br _extended="true" />
　　 例如，如下的数据库表是符合第一范式的：<br _extended="true" />
<br _extended="true" />
</p>
<table height="43" cellspacing="0" cellpadding="2" align="center" border="1" _extended="true">
    <tbody _extended="true">
        <tr _extended="true">
            <td height="18" _extended="true">字段1</td>
            <td _extended="true">字段2</td>
            <td _extended="true">字段3</td>
            <td _extended="true">字段4</td>
        </tr>
        <tr _extended="true">
            <td height="23" _extended="true">　　</td>
            <td _extended="true">　　</td>
            <td _extended="true">　　</td>
            <td _extended="true">　　</td>
        </tr>
    </tbody>
</table>
<br _extended="true" />
　　 而这样的数据库表是不符合第一范式的：<br _extended="true" />
<br _extended="true" />
<table height="25" cellspacing="0" cellpadding="2" align="center" border="1" _extended="true">
    <tbody _extended="true">
        <tr _extended="true">
            <td _extended="true">字段1</td>
            <td _extended="true">字段2</td>
            <td colspan="2" _extended="true">字段3</td>
            <td _extended="true">字段4</td>
        </tr>
        <tr _extended="true">
            <td _extended="true">　　</td>
            <td _extended="true">　　</td>
            <td _extended="true">字段3.1</td>
            <td _extended="true">字段3.2</td>
            <td _extended="true">　　</td>
        </tr>
    </tbody>
</table>
<p class="main" _extended="true"><br _extended="true" />
　　很显然，在当前的任何关系数据库管理系统（DBMS）中，傻瓜也不可能做出不符合第一范式的数据库，因为这些DBMS不允许你把数据库表的一列再分成二列或多列。因此，你想在现有的DBMS中设计出不符合第一范式的数据库都是不可能的。<br _extended="true" />
<br _extended="true" />
　　 <strong _extended="true">第二范式（2NF）：</strong>数据库表中不存在非关键字段对任一候选关键字段的部分函数依赖（部分函数依赖指的是存在组合关键字中的某些字段决定非关键字段的情况），也即所有非关键字段都完全依赖于任意一组候选关键字。<br _extended="true" />
<br _extended="true" />
　　 假定选课关系表为SelectCourse(学号, 姓名, 年龄, 课程名称, 成绩, 学分)，关键字为组合关键字(学号, 课程名称)，因为存在如下决定关系：<br _extended="true" />
<br _extended="true" />
　　 (学号, 课程名称) &#8594; (姓名, 年龄, 成绩, 学分)<br _extended="true" />
<br _extended="true" />
　　 这个数据库表不满足第二范式，因为存在如下决定关系：<br _extended="true" />
<br _extended="true" />
　　 (课程名称) &#8594; (学分)<br _extended="true" />
<br _extended="true" />
　　 (学号) &#8594; (姓名, 年龄)<br _extended="true" />
<br _extended="true" />
　　 即存在组合关键字中的字段决定非关键字的情况。<br _extended="true" />
<br _extended="true" />
　　 由于不符合2NF，这个选课关系表会存在如下问题：<br _extended="true" />
<br _extended="true" />
　　 (1) 数据冗余：<br _extended="true" />
<br _extended="true" />
　　同一门课程由n个学生选修，"学分"就重复n-1次；同一个学生选修了m门课程，姓名和年龄就重复了m-1次。<br _extended="true" />
<br _extended="true" />
　　 (2) 更新异常：<br _extended="true" />
<br _extended="true" />
　　若调整了某门课程的学分，数据表中所有行的"学分"值都要更新，否则会出现同一门课程学分不同的情况。<br _extended="true" />
<br _extended="true" />
　　 (3) 插入异常：<br _extended="true" />
<br _extended="true" />
　　假设要开设一门新的课程，暂时还没有人选修。这样，由于还没有"学号"关键字，课程名称和学分也无法记录入数据库。<br _extended="true" />
<br _extended="true" />
　　 (4) 删除异常：<br _extended="true" />
<br _extended="true" />
　　假设一批学生已经完成课程的选修，这些选修记录就应该从数据库表中删除。但是，与此同时，课程名称和学分信息也被删除了。很显然，这也会导致插入异常。<br _extended="true" />
<br _extended="true" />
　　 把选课关系表SelectCourse改为如下三个表：<br _extended="true" />
<br _extended="true" />
　　 学生：Student(学号, 姓名, 年龄)；<br _extended="true" />
<br _extended="true" />
　　 课程：Course(课程名称, 学分)；<br _extended="true" />
<br _extended="true" />
　　 选课关系：SelectCourse(学号, 课程名称, 成绩)。<br _extended="true" />
<br _extended="true" />
　　这样的数据库表是符合第二范式的，消除了数据冗余、更新异常、插入异常和删除异常。<br _extended="true" />
<br _extended="true" />
　　另外，所有单关键字的数据库表都符合第二范式，因为不可能存在组合关键字。<br _extended="true" />
<br _extended="true" />
　　 <strong _extended="true">第三范式（3NF）：</strong>在第二范式的基础上，数据表中如果不存在非关键字段对任一候选关键字段的传递函数依赖则符合第三范式。所谓传递函数依赖，指的是如果存在"A &#8594; B &#8594; C"的决定关系，则C传递函数依赖于A。因此，满足第三范式的数据库表应该不存在如下依赖关系：<br _extended="true" />
<br _extended="true" />
　　 关键字段 &#8594; 非关键字段x &#8594; 非关键字段y<br _extended="true" />
<br _extended="true" />
　　 假定学生关系表为Student(学号, 姓名, 年龄, 所在学院, 学院地点, 学院电话)，关键字为单一关键字"学号"，因为存在如下决定关系：<br _extended="true" />
<br _extended="true" />
　　 (学号) &#8594; (姓名, 年龄, 所在学院, 学院地点, 学院电话)<br _extended="true" />
<br _extended="true" />
　　这个数据库是符合2NF的，但是不符合3NF，因为存在如下决定关系：<br _extended="true" />
<br _extended="true" />
　　 (学号) &#8594; (所在学院) &#8594; (学院地点, 学院电话)<br _extended="true" />
<br _extended="true" />
　　即存在非关键字段"学院地点"、"学院电话"对关键字段"学号"的传递函数依赖。<br _extended="true" />
<br _extended="true" />
　　它也会存在数据冗余、更新异常、插入异常和删除异常的情况，读者可自行分析得知。<br _extended="true" />
<br _extended="true" />
　　 把学生关系表分为如下两个表：<br _extended="true" />
<br _extended="true" />
　　 学生：(学号, 姓名, 年龄, 所在学院)；<br _extended="true" />
<br _extended="true" />
　　 学院：(学院, 地点, 电话)。<br _extended="true" />
<br _extended="true" />
　　这样的数据库表是符合第三范式的，消除了数据冗余、更新异常、插入异常和删除异常。<br _extended="true" />
<br _extended="true" />
　　 <strong _extended="true">鲍依斯-科得范式（BCNF）：</strong>在第三范式的基础上，数据库表中如果不存在任何字段对任一候选关键字段的传递函数依赖则符合第三范式。<br _extended="true" />
<br _extended="true" />
　　 假设仓库管理关系表为StorehouseManage(仓库ID, 存储物品ID, 管理员ID, 数量)，且有一个管理员只在一个仓库工作；一个仓库可以存储多种物品。这个数据库表中存在如下决定关系：<br _extended="true" />
<br _extended="true" />
　　 (仓库ID, 存储物品ID) &#8594;(管理员ID, 数量)<br _extended="true" />
<br _extended="true" />
　　 (管理员ID, 存储物品ID) &#8594; (仓库ID, 数量)<br _extended="true" />
<br _extended="true" />
　　 所以，(仓库ID, 存储物品ID)和(管理员ID, 存储物品ID)都是StorehouseManage的候选关键字，表中的唯一非关键字段为数量，它是符合第三范式的。但是，由于存在如下决定关系：<br _extended="true" />
<br _extended="true" />
　　 (仓库ID) &#8594; (管理员ID)<br _extended="true" />
<br _extended="true" />
　　 (管理员ID) &#8594; (仓库ID)<br _extended="true" />
<br _extended="true" />
　　即存在关键字段决定关键字段的情况，所以其不符合BCNF范式。它会出现如下异常情况：<br _extended="true" />
<br _extended="true" />
　　 (1) 删除异常：<br _extended="true" />
<br _extended="true" />
　　当仓库被清空后，所有"存储物品ID"和"数量"信息被删除的同时，"仓库ID"和"管理员ID"信息也被删除了。<br _extended="true" />
<br _extended="true" />
　　 (2) 插入异常：<br _extended="true" />
<br _extended="true" />
　　 当仓库没有存储任何物品时，无法给仓库分配管理员。<br _extended="true" />
<br _extended="true" />
　　 (3) 更新异常：<br _extended="true" />
<br _extended="true" />
　　 如果仓库换了管理员，则表中所有行的管理员ID都要修改。<br _extended="true" />
<br _extended="true" />
　　 把仓库管理关系表分解为二个关系表：<br _extended="true" />
<br _extended="true" />
　　 仓库管理：StorehouseManage(仓库ID, 管理员ID)；<br _extended="true" />
<br _extended="true" />
　　 仓库：Storehouse(仓库ID, 存储物品ID, 数量)。<br _extended="true" />
<br _extended="true" />
　　这样的数据库表是符合BCNF范式的，消除了删除异常、插入异常和更新异常。</p>
<p class="cnt" _extended="true"><strong _extended="true">　　 范式应用</strong><br _extended="true" />
<br _extended="true" />
　　 我们来逐步搞定一个论坛的数据库，有如下信息：<br _extended="true" />
<br _extended="true" />
　　 （1） 用户：用户名，email，主页，电话，联系地址<br _extended="true" />
<br _extended="true" />
　　 （2） 帖子：发帖标题，发帖内容，回复标题，回复内容<br _extended="true" />
<br _extended="true" />
　　 第一次我们将数据库设计为仅仅存在表：<br _extended="true" />
</p>
<p class="cnt" _extended="true">?/P&gt;</p>
<table height="25" cellspacing="0" cellpadding="2" align="center" border="1" _extended="true">
    <tbody _extended="true">
        <tr _extended="true">
            <td _extended="true">用户名</td>
            <td _extended="true">email</td>
            <td _extended="true">主页</td>
            <td _extended="true">电话</td>
            <td _extended="true">联系地址</td>
            <td _extended="true">发帖标题</td>
            <td _extended="true">发帖内容</td>
            <td _extended="true">回复标题</td>
            <td _extended="true">回复内容</td>
        </tr>
    </tbody>
</table>
<br _extended="true" />
　　这个数据库表符合第一范式，但是没有任何一组候选关键字能决定数据库表的整行，唯一的关键字段用户名也不能完全决定整个元组。我们需要增加"发帖ID"、"回复ID"字段，即将表修改为：<br _extended="true" />
<br _extended="true" />
<table height="25" cellspacing="0" cellpadding="2" align="center" border="1" _extended="true">
    <tbody _extended="true">
        <tr _extended="true">
            <td _extended="true">用户名</td>
            <td _extended="true">email</td>
            <td _extended="true">主页</td>
            <td _extended="true">电话</td>
            <td _extended="true">联系地址</td>
            <td _extended="true">发帖ID</td>
            <td _extended="true">发帖标题</td>
            <td _extended="true">发帖内容</td>
            <td _extended="true">回复ID</td>
            <td _extended="true">回复标题</td>
            <td _extended="true">回复内容</td>
        </tr>
    </tbody>
</table>
<br _extended="true" />
　　 这样数据表中的关键字(用户名，发帖ID，回复ID)能决定整行：<br _extended="true" />
<br _extended="true" />
　　 (用户名,发帖ID,回复ID) &#8594; (email,主页,电话,联系地址,发帖标题,发帖内容,回复标题,回复内容)<br _extended="true" />
<br _extended="true" />
　　 但是，这样的设计不符合第二范式，因为存在如下决定关系：<br _extended="true" />
<br _extended="true" />
　　 (用户名) &#8594; (email,主页,电话,联系地址)<br _extended="true" />
<br _extended="true" />
　　 (发帖ID) &#8594; (发帖标题,发帖内容)<br _extended="true" />
<br _extended="true" />
　　 (回复ID) &#8594; (回复标题,回复内容)<br _extended="true" />
<br _extended="true" />
　　即非关键字段部分函数依赖于候选关键字段，很明显，这个设计会导致大量的数据冗余和操作异常。<br _extended="true" />
<br _extended="true" />
　　 我们将数据库表分解为（带下划线的为关键字）：<br _extended="true" />
<br _extended="true" />
　　 （1） 用户信息：用户名，email，主页，电话，联系地址<br _extended="true" />
<br _extended="true" />
　　 （2） 帖子信息：发帖ID，标题，内容<br _extended="true" />
<br _extended="true" />
　　 （3） 回复信息：回复ID，标题，内容<br _extended="true" />
<br _extended="true" />
　　 （4） 发贴：用户名，发帖ID<br _extended="true" />
<br _extended="true" />
　　 （5） 回复：发帖ID，回复ID<br _extended="true" />
<br _extended="true" />
　　这样的设计是满足第1、2、3范式和BCNF范式要求的，但是这样的设计是不是最好的呢？<br _extended="true" />
<br _extended="true" />
　　 不一定。<br _extended="true" />
<br _extended="true" />
　　观察可知，第4项"发帖"中的"用户名"和"发帖ID"之间是1：N的关系，因此我们可以把"发帖"合并到第2项的"帖子信息"中；第5项"回复"中的"发帖ID"和"回复ID"之间也是1：N的关系，因此我们可以把"回复"合并到第3项的"回复信息"中。这样可以一定量地减少数据冗余，新的设计为：<br _extended="true" />
<br _extended="true" />
　　 （1） 用户信息：用户名，email，主页，电话，联系地址<br _extended="true" />
<br _extended="true" />
　　 （2） 帖子信息：用户名，发帖ID，标题，内容<br _extended="true" />
<br _extended="true" />
　　 （3） 回复信息：发帖ID，回复ID，标题，内容<br _extended="true" />
<br _extended="true" />
　　 数据库表1显然满足所有范式的要求；<br _extended="true" />
<br _extended="true" />
　　数据库表2中存在非关键字段"标题"、"内容"对关键字段"发帖ID"的部分函数依赖，即不满足第二范式的要求，但是这一设计并不会导致数据冗余和操作异常；<br _extended="true" />
<br _extended="true" />
　　数据库表3中也存在非关键字段"标题"、"内容"对关键字段"回复ID"的部分函数依赖，也不满足第二范式的要求，但是与数据库表2相似，这一设计也不会导致数据冗余和操作异常。<br _extended="true" />
<br _extended="true" />
　　由此可以看出，并不一定要强行满足范式的要求，对于1：N关系，当1的一边合并到N的那边后，N的那边就不再满足第二范式了，但是这种设计反而比较好！<br _extended="true" />
<br _extended="true" />
　　对于M：N的关系，不能将M一边或N一边合并到另一边去，这样会导致不符合范式要求，同时导致操作异常和数据冗余。<br _extended="true" />
对于1：1的关系，我们可以将左边的1或者右边的1合并到另一边去，设计导致不符合范式要求，但是并不会导致操作异常和数据冗余。<br _extended="true" />
<br _extended="true" />
<strong _extended="true">　　 结论</strong><br _extended="true" />
<br _extended="true" />
　　满足范式要求的数据库设计是结构清晰的，同时可避免数据冗余和操作异常。这并意味着不符合范式要求的设计一定是错误的，在数据库表中存在1：1或1：N关系这种较特殊的情况下，合并导致的不符合范式要求反而是合理的。<br _extended="true" />
<br _extended="true" />
　　 在我们设计数据库的时候，一定要时刻考虑范式的要求。 
<img src ="http://www.blogjava.net/jesenblog/aggbug/188262.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jesenblog/" target="_blank">白露</a> 2008-03-24 15:34 <a href="http://www.blogjava.net/jesenblog/articles/188262.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>oracle 认证方式总结 </title><link>http://www.blogjava.net/jesenblog/articles/188260.html</link><dc:creator>白露</dc:creator><author>白露</author><pubDate>Mon, 24 Mar 2008 07:33:00 GMT</pubDate><guid>http://www.blogjava.net/jesenblog/articles/188260.html</guid><wfw:comment>http://www.blogjava.net/jesenblog/comments/188260.html</wfw:comment><comments>http://www.blogjava.net/jesenblog/articles/188260.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jesenblog/comments/commentRss/188260.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jesenblog/services/trackbacks/188260.html</trackback:ping><description><![CDATA[<div align="left" _extended="true"><span style="font-size: 9pt; color: #333333" _extended="true">ORACLE</span><span style="font-size: 9pt; color: #333333" _extended="true">数据库通过</span><span style="font-size: 9pt; color: #333333" _extended="true">sqlnet.ora</span><span style="font-size: 9pt; color: #333333" _extended="true">文件中的参数</span><span style="font-size: 9pt; color: #333333" _extended="true">sqlnet.authentication_services,</span><span style="font-size: 9pt; color: #333333" _extended="true">参数文件中的</span><span style="font-size: 9pt; color: #333333" _extended="true">remote_login_passwordfile</span><span style="font-size: 9pt; color: #333333" _extended="true">和口令文件</span><span style="font-size: 9pt; color: #333333" _extended="true">pwdsid.ora</span><span style="font-size: 9pt; color: #333333" _extended="true">三者协同作用实现身份认证</span><span style="font-size: 9pt; color: #333333" _extended="true">.<br _extended="true" />
<br _extended="true" />
Sqlnet.authentication_services=(NTS)|(NONE)<br _extended="true" />
NTS:</span><span style="font-size: 9pt; color: #333333" _extended="true">操作系统认证方式</span><span style="font-size: 9pt; color: #333333" _extended="true">,</span><span style="font-size: 9pt; color: #333333" _extended="true">不使用口令文件</span><span style="font-size: 9pt; color: #333333" _extended="true">;<br _extended="true" />
NONE:</span><span style="font-size: 9pt; color: #333333" _extended="true">口令文件认证方式</span><span style="font-size: 9pt; color: #333333" _extended="true"><br _extended="true" />
<br _extended="true" />
Remote_login_passwordfile=(NONE)|(EXCLUSIVE)|(SHARED)<br _extended="true" />
NONE:</span><span style="font-size: 9pt; color: #333333" _extended="true">不使用口令文件</span><span style="font-size: 9pt; color: #333333" _extended="true">,</span><span style="font-size: 9pt; color: #333333" _extended="true">操作系统认证</span><span style="font-size: 9pt; color: #333333" _extended="true">;<br _extended="true" />
EXCLUSIVE:</span><span style="font-size: 9pt; color: #333333" _extended="true">口令文件认证方式</span><span style="font-size: 9pt; color: #333333" _extended="true">,</span><span style="font-size: 9pt; color: #333333" _extended="true">但只有一个数据库实例可以使用此文件</span><span style="font-size: 9pt; color: #333333" _extended="true">;<br _extended="true" />
SHARED:</span><span style="font-size: 9pt; color: #333333" _extended="true">口令文件认证方式</span><span style="font-size: 9pt; color: #333333" _extended="true">,</span><span style="font-size: 9pt; color: #333333" _extended="true">可以有多个数据库实例可以使用此文件</span><span style="font-size: 9pt; color: #333333" _extended="true">,</span><span style="font-size: 9pt; color: #333333" _extended="true">但此设置下只有</span><span style="font-size: 9pt; color: #333333" _extended="true">SYS</span><span style="font-size: 9pt; color: #333333" _extended="true">帐号能被识别</span><span style="font-size: 9pt; color: #333333" _extended="true">,</span><span style="font-size: 9pt; color: #333333" _extended="true">即使文件中存在其他用户的信息</span><span style="font-size: 9pt; color: #333333" _extended="true">,</span><span style="font-size: 9pt; color: #333333" _extended="true">也不允许他们以</span><span style="font-size: 9pt; color: #333333" _extended="true">SYSOPER/SYSDBA</span><span style="font-size: 9pt; color: #333333" _extended="true">登录</span><span style="font-size: 9pt; color: #333333" _extended="true">.<br _extended="true" />
<br _extended="true" />
(1).sqlnet.authentication_services=(NTS)<br _extended="true" />
</span><span style="font-size: 9pt; color: #333333" _extended="true">同时</span><span style="font-size: 9pt; color: #333333" _extended="true">Remote_login_passwordfile=(NONE),</span><span style="font-size: 9pt; color: #333333" _extended="true">此时为操作系统认证方式</span><span style="font-size: 9pt; color: #333333" _extended="true">.<br _extended="true" />
<br _extended="true" />
</span><span style="font-size: 9pt; color: #333333" _extended="true">当以</span><span style="font-size: 9pt; color: #333333" _extended="true">oracle_dba</span><span style="font-size: 9pt; color: #333333" _extended="true">组下的用户登录进入本地的操作系统后</span><span style="font-size: 9pt; color: #333333" _extended="true">,</span><span style="font-size: 9pt; color: #333333" _extended="true">进行以下操作</span><span style="font-size: 9pt; color: #333333" _extended="true">:<br _extended="true" />
sqlplus /nolog<br _extended="true" />
SQL&gt;conn</span> <strong _extended="true"><u _extended="true"><span style="font-size: 9pt; color: red" _extended="true">/</span></u></strong><strong _extended="true"><u _extended="true"><span style="font-size: 9pt; color: red" _extended="true">as</span></u></strong><strong _extended="true"><u _extended="true"><span style="font-size: 9pt; color: red" _extended="true">sysdba</span></u></strong><span style="font-size: 9pt; color: #333333" _extended="true"><br _extended="true" />
</span><span style="font-size: 9pt; color: #333333" _extended="true">可以以</span><strong _extended="true"><u _extended="true"><span style="font-size: 9pt; color: red" _extended="true">sysdba</span></u></strong><span style="font-size: 9pt; color: #333333" _extended="true">身份登录成功</span><span style="font-size: 9pt; color: #333333" _extended="true">,</span><span style="font-size: 9pt; color: #333333" _extended="true">进行数据库方面的操作</span><span style="font-size: 9pt; color: #333333" _extended="true">.<br _extended="true" />
<br _extended="true" />
</span><span style="font-size: 9pt; color: #333333" _extended="true">当以远程进行登录时</span><span style="font-size: 9pt; color: #333333" _extended="true">,</span><span style="font-size: 9pt; color: #333333" _extended="true">执行</span><span style="font-size: 9pt; color: #333333" _extended="true">:<br _extended="true" />
sqlplus /nolog<br _extended="true" />
SQL&gt;conn</span> <strong _extended="true"><u _extended="true"><span style="font-size: 9pt; color: red" _extended="true">/</span></u></strong><strong _extended="true"><u _extended="true"><span style="font-size: 9pt; color: red" _extended="true">as</span></u></strong><strong _extended="true"><u _extended="true"><span style="font-size: 9pt; color: red" _extended="true">sysdba</span></u></strong><span style="font-size: 9pt; color: #333333" _extended="true"><br _extended="true" />
</span><span style="font-size: 9pt; color: #333333" _extended="true">则会显示</span><span style="font-size: 9pt; color: #333333" _extended="true">:<br _extended="true" />
ERROR:ORA-01031:insufficient privileges<br _extended="true" />
</span><span style="font-size: 9pt; color: #333333" _extended="true">即不允许以</span><strong _extended="true"><u _extended="true"><span style="font-size: 9pt; color: red" _extended="true">sysdba</span></u></strong><span style="font-size: 9pt; color: #333333" _extended="true">身份远程登录系统</span><span style="font-size: 9pt; color: #333333" _extended="true">,</span><span style="font-size: 9pt; color: #333333" _extended="true">这也是</span><span style="font-size: 9pt; color: #333333" _extended="true">OS</span><span style="font-size: 9pt; color: #333333" _extended="true">认证这所以称为本地认证方式的原因</span><span style="font-size: 9pt; color: #333333" _extended="true">.<br _extended="true" />
<br _extended="true" />
(2).Sqlnet.authentication_services=(NONE),</span><span style="font-size: 9pt; color: #333333" _extended="true">同时</span><span style="font-size: 9pt; color: #333333" _extended="true"><br _extended="true" />
Remote_login_passwordfile=(EXCLUSIVE)|(SHARED),</span><span style="font-size: 9pt; color: #333333" _extended="true">配合口令文件</span><span style="font-size: 9pt; color: #333333" _extended="true">PWDsid.ora,</span><span style="font-size: 9pt; color: #333333" _extended="true">此时为口令文件认证方式</span><span style="font-size: 9pt; color: #333333" _extended="true">:<br _extended="true" />
<br _extended="true" />
</span><span style="font-size: 9pt; color: #333333" _extended="true">当在本地以</span><span style="font-size: 9pt; color: #333333" _extended="true">oracle_dba</span><span style="font-size: 9pt; color: #333333" _extended="true">组下的用户登录进入系统时</span><span style="font-size: 9pt; color: #333333" _extended="true">,</span><span style="font-size: 9pt; color: #333333" _extended="true">进行以下操作</span><span style="font-size: 9pt; color: #333333" _extended="true">:<br _extended="true" />
sqlplus /nolog<br _extended="true" />
SQL&gt;conn</span> <strong _extended="true"><u _extended="true"><span style="font-size: 9pt; color: red" _extended="true">/</span></u></strong><strong _extended="true"><u _extended="true"><span style="font-size: 9pt; color: red" _extended="true">as</span></u></strong><strong _extended="true"><u _extended="true"><span style="font-size: 9pt; color: red" _extended="true">sysdba</span></u></strong><span style="font-size: 9pt; color: #333333" _extended="true"><br _extended="true" />
</span><span style="font-size: 9pt; color: #333333" _extended="true">则会显示</span><span style="font-size: 9pt; color: #333333" _extended="true">:<br _extended="true" />
ERROR:ORA-01031:insufficient privileges<br _extended="true" />
<br _extended="true" />
</span><span style="font-size: 9pt; color: #333333" _extended="true">在本地或远程进行下边的操作</span><span style="font-size: 9pt; color: #333333" _extended="true">:<br _extended="true" />
sqlplus /nolog<br _extended="true" />
SQL&gt;conn sys/</span><span style="font-size: 9pt; color: #333333" _extended="true">密码</span><span style="font-size: 9pt; color: #333333" _extended="true">@</span><span style="font-size: 9pt; color: #333333" _extended="true">服务名</span><strong _extended="true"><u _extended="true"><span style="font-size: 9pt; color: red" _extended="true">as</span></u></strong><strong _extended="true"><u _extended="true"><span style="font-size: 9pt; color: red" _extended="true">sysdba</span></u></strong><span style="font-size: 9pt; color: #333333" _extended="true"><br _extended="true" />
</span><span style="font-size: 9pt; color: #333333" _extended="true">可以进入系统</span><span style="font-size: 9pt; color: #333333" _extended="true">,</span><span style="font-size: 9pt; color: #333333" _extended="true">也就是说口令文件认证方式允许用户从本地或远程以</span><strong _extended="true"><u _extended="true"><span style="font-size: 9pt; color: red" _extended="true">sysdba</span></u></strong><span style="font-size: 9pt; color: #333333" _extended="true">身份登录</span><span style="font-size: 9pt; color: #333333" _extended="true">,</span><span style="font-size: 9pt; color: #333333" _extended="true">但必须提供口令字</span><span style="font-size: 9pt; color: #333333" _extended="true">.<br _extended="true" />
<br _extended="true" />
<br _extended="true" />
(3).Sqlnet.authentication_services=(NTS),</span><span style="font-size: 9pt; color: #333333" _extended="true">同时</span><span style="font-size: 9pt; color: #333333" _extended="true"><br _extended="true" />
Remote_login_passwordfile=(EXCLUSIVE)|(SHARED),</span><span style="font-size: 9pt; color: #333333" _extended="true">配合口令文件</span><span style="font-size: 9pt; color: #333333" _extended="true">PWDsid.ora,</span><span style="font-size: 9pt; color: #333333" _extended="true">此时为操作系统认证和口令文件认证同时起作用</span><span style="font-size: 9pt; color: #333333" _extended="true">:<br _extended="true" />
<br _extended="true" />
</span><span style="font-size: 9pt; color: #333333" _extended="true">当在本地以</span><span style="font-size: 9pt; color: #333333" _extended="true">oracle_dba</span><span style="font-size: 9pt; color: #333333" _extended="true">组下的用户登录进入操作系统后</span><span style="font-size: 9pt; color: #333333" _extended="true">,</span><span style="font-size: 9pt; color: #333333" _extended="true">进行下边的操作</span><span style="font-size: 9pt; color: #333333" _extended="true">:<br _extended="true" />
sqlplus /nolog<br _extended="true" />
SQL&gt;conn</span> <strong _extended="true"><u _extended="true"><span style="font-size: 9pt; color: red" _extended="true">/</span></u></strong><strong _extended="true"><u _extended="true"><span style="font-size: 9pt; color: red" _extended="true">as</span></u></strong><strong _extended="true"><u _extended="true"><span style="font-size: 9pt; color: red" _extended="true">sysdba</span></u></strong><span style="font-size: 9pt; color: #333333" _extended="true"><br _extended="true" />
</span><span style="font-size: 9pt; color: #333333" _extended="true">可以进入系统</span><span style="font-size: 9pt; color: #333333" _extended="true">.</span><span style="font-size: 9pt; color: #333333" _extended="true">即操作系统认证方式登录成功</span><span style="font-size: 9pt; color: #333333" _extended="true">.<br _extended="true" />
<br _extended="true" />
</span><span style="font-size: 9pt; color: #333333" _extended="true">当在远程执行</span><span style="font-size: 9pt; color: #333333" _extended="true">:<br _extended="true" />
sqlplus /nolog<br _extended="true" />
SQL&gt;conn sys/</span><span style="font-size: 9pt; color: #333333" _extended="true">密码</span><span style="font-size: 9pt; color: #333333" _extended="true">@</span><span style="font-size: 9pt; color: #333333" _extended="true">服务名</span><strong _extended="true"><u _extended="true"><span style="font-size: 9pt; color: red" _extended="true">as</span></u></strong><strong _extended="true"><u _extended="true"><span style="font-size: 9pt; color: red" _extended="true">sysdba</span></u></strong><span style="font-size: 9pt; color: #333333" _extended="true"><br _extended="true" />
</span><span style="font-size: 9pt; color: #333333" _extended="true">同时可正常登录到数据库系统</span><span style="font-size: 9pt; color: #333333" _extended="true">,</span><span style="font-size: 9pt; color: #333333" _extended="true">即口令文件认证方式登录成功</span><span style="font-size: 9pt; color: #333333" _extended="true">.</span></div>
<div _extended="true">&nbsp;</div>
<div _extended="true">&nbsp;</div>
<div _extended="true">附：</div>
<div _extended="true"><span style="font-size: 9pt; color: #333333" _extended="true">要知道以下几种登陆方式不是一种概念</span><span style="font-size: 9pt; color: #333333" _extended="true"><br _extended="true" />
sqlplus /nolog<br _extended="true" />
1:&nbsp;&nbsp;conn</span> <strong _extended="true"><u _extended="true"><span style="font-size: 9pt; color: red" _extended="true">/</span></u></strong><strong _extended="true"><u _extended="true"><span style="font-size: 9pt; color: red" _extended="true">as</span></u></strong><strong _extended="true"><u _extended="true"><span style="font-size: 9pt; color: red" _extended="true">sysdba</span></u></strong><span style="font-size: 9pt; color: #333333" _extended="true">&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;</span><span style="font-size: 9pt; color: #333333" _extended="true">本机登陆，使用操作系统认证，有无监听都可以</span><span style="font-size: 9pt; color: #333333" _extended="true"><br _extended="true" />
2:&nbsp;&nbsp;conn sys/password</span> <strong _extended="true"><u _extended="true"><span style="font-size: 9pt; color: red" _extended="true">as</span></u></strong><strong _extended="true"><u _extended="true"><span style="font-size: 9pt; color: red" _extended="true">sysdba</span></u></strong><span style="font-size: 9pt; color: #333333" _extended="true">&nbsp; &nbsp;</span><span style="font-size: 9pt; color: #333333" _extended="true">本机登陆，使用密码文件认证，有无监听都可以</span><span style="font-size: 9pt; color: #333333" _extended="true"><br _extended="true" />
3:&nbsp;&nbsp;conn sys/password@dbanote</span> <strong _extended="true"><u _extended="true"><span style="font-size: 9pt; color: red" _extended="true">as</span></u></strong><strong _extended="true"><u _extended="true"><span style="font-size: 9pt; color: red" _extended="true">sysdba</span></u></strong><span style="font-size: 9pt; color: #333333" _extended="true">&nbsp;&nbsp;</span><span style="font-size: 9pt; color: #333333" _extended="true">可以本机可以远程，使用密码文件认证，必须有监听，必须有</span><span style="font-size: 9pt; color: #333333" _extended="true">tnsnames.ora,remote_login_passwordfile</span><span style="font-size: 9pt; color: #333333" _extended="true">必须是</span><span style="font-size: 9pt; color: #333333" _extended="true">EXCLUSIVE</span></div>
<img src ="http://www.blogjava.net/jesenblog/aggbug/188260.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jesenblog/" target="_blank">白露</a> 2008-03-24 15:33 <a href="http://www.blogjava.net/jesenblog/articles/188260.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>数据库名、实例名、数据库域名、全局数据库名、服务名详解 </title><link>http://www.blogjava.net/jesenblog/articles/188259.html</link><dc:creator>白露</dc:creator><author>白露</author><pubDate>Mon, 24 Mar 2008 07:32:00 GMT</pubDate><guid>http://www.blogjava.net/jesenblog/articles/188259.html</guid><wfw:comment>http://www.blogjava.net/jesenblog/comments/188259.html</wfw:comment><comments>http://www.blogjava.net/jesenblog/articles/188259.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jesenblog/comments/commentRss/188259.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jesenblog/services/trackbacks/188259.html</trackback:ping><description><![CDATA[<span style="font-size: 12pt" _extended="true">数据库名、实例名、数据库域名、全局数据库名、服务名，<br _extended="true" />
这是几个令很多初学者容易混淆的概念。相信很多初学者都与我一样被标题上这些个概念搞得一头雾水。我们现在就来把它们弄个明白。</span>
<div align="left" _extended="true"><br _extended="true" />
</div>
<p _extended="true"><font face="宋体" _extended="true"><font size="3" _extended="true"><strong _extended="true"><span style="color: red" _extended="true"><font face="宋体" _extended="true"><font size="3" _extended="true"><strong style="font-size: 14pt" _extended="true">一、数据库名<br _extended="true" />
</strong></font></font></span><br _extended="true" />
什么是数据库名？</strong><br _extended="true" />
数据库名就是一个数据库的标识，就像人的身份证号一样。他用参数DB_NAME表示，如果一台机器上装了多全数据库，那么每一个数据库都有一个数据库名。在数据库安装或创建完成之后，参数DB_NAME被写入参数文件之中。格式如下：<br _extended="true" />
DB_NAME=myorcl<br _extended="true" />
...<br _extended="true" />
在创建数据库时就应考虑好数据库名，并且在创建完数据库之后，数据库名不宜修改，即使要修改也会很麻烦。因为，数据库名还被写入控制文件中，控制文件是以二进制型式存储的，用户无法修改控制文件的内容。假设用户修改了参数文件中的数据库名，即修改DB_NAME的值。但是在Oracle启动时，由于参数文件中的DB_NAME与控制文件中的数据库名不一致，导致数据库启动失败，将返回ORA-01103错误。</font></font></p>
<p _extended="true"><font face="宋体" _extended="true"><font size="3" _extended="true"><strong _extended="true">数据库名的作用</strong><br _extended="true" />
数据库名是在安装数据库、创建新的数据库、创建数据库控制文件、修改数据结构、备份与恢复数据库时都需要使用到的。<br _extended="true" />
有很多Oracle安装文件目录是与数据库名相关的，如：<br _extended="true" />
winnt: d:\oracle\product\10.1.0\oradata\DB_NAME\...<br _extended="true" />
Unix: /home/app/oracle/product/10.1.0/oradata/DB_NAME/...<br _extended="true" />
pfile:<br _extended="true" />
winnt: d:\oracle\product\10.1.0\admin\DB_NAME\pfile\ini.ora<br _extended="true" />
Unix: /home/app/oracle/product/10.1.0/admin/DB_NAME/pfile/init$ORACLE_SID.ora<br _extended="true" />
跟踪文件目录：<br _extended="true" />
winnt: /home/app/oracle/product/10.1.0/admin/DB_NAME/bdump/...<br _extended="true" />
另外，在创建数据时，careate database命令中的数据库名也要与参数文件中DB_NAME参数的值一致，否则将产生错误。<br _extended="true" />
同样，修改数据库结构的语句 alter database，当然也要指出要修改的数据库的名称。<br _extended="true" />
如果控制文件损坏或丢失，数据库将不能加载，这时要重新创建控制文件，方法是以nomount方式启动实例，然后以create controlfile命令创建控制文件，当然这个命令中也是指指DB_NAME。<br _extended="true" />
还有在备份或恢复数据库时，都需要用到数据库名。<br _extended="true" />
总之，数据库名很重要，要准确理解它的作用。</font></font></p>
<p _extended="true"><font face="宋体" _extended="true"><font size="3" _extended="true"><strong _extended="true">查询当前数据名</strong><br _extended="true" />
方法一:select name from v$database;<br _extended="true" />
方法二：show parameter db<br _extended="true" />
方法三：查看参数文件。</font></font></p>
<p _extended="true"><font face="宋体" _extended="true"><font size="3" _extended="true"><strong _extended="true">修改数据库名</strong><br _extended="true" />
前面建议：应在创建数据库时就确定好数据库名，数据库名不应作修改，因为修改数据库名是一件比较复杂的事情。那么现在就来说明一下，如何在已创建数据之后，修改数据库名。步骤如下：<br _extended="true" />
1.关闭数据库。<br _extended="true" />
2.修改数据库参数文件中的DB_NAME参数的值为新的数据库名。<br _extended="true" />
3. 以NOMOUNT方式启动实例，修建控制文件(有关创建控制文件的命令语法，请参考oracle文档)</font></font></p>
<p _extended="true"><font face="宋体" _extended="true"><font size="3" _extended="true"><strong style="color: red" _extended="true">二、数据库实例名<br _extended="true" />
</strong><br _extended="true" />
</font></font><font face="宋体" _extended="true"><font size="3" _extended="true"><strong _extended="true">什么是数据库实例名？<br _extended="true" />
</strong>数据库实例名是用于和操作系统进行联系的标识，就是说数据库和操作系统之间的交互用的是数据库实例名。实例名也被写入参数文件中，该参数为instance_name，在 winnt平台中，实例名同时也被写入注册表。<br _extended="true" />
数据库名和实例名可以相同也可以不同。<br _extended="true" />
在一般情况下，数据库名和实例名是一对一的关系，但如果在oracle并行服务器架构(即oracle实时应用集群)中，数据库名和实例名是一对多的关系。这一点在第一篇中已有图例说明。</font></font></p>
<p _extended="true"><font face="宋体" _extended="true"><font size="3" _extended="true"><strong _extended="true">查询当前数据库实例名</strong><br _extended="true" />
方法一：select instance_name from v$instance;<br _extended="true" />
方法二：show parameter instance<br _extended="true" />
方法三：在参数文件中查询。</font></font></p>
<p _extended="true"><font face="宋体" _extended="true"><font size="3" _extended="true"><strong _extended="true">数据库实例名与ORACLE_SID</strong><br _extended="true" />
虽然两者都表是oracle实例，但两者是有区别的。instance_name是oracle数据库参数。而ORACLE_SID是操作系统的环境变量。 ORACLD_SID用于与操作系统交互，也就是说，从操作系统的角度访问实例名，必须通过ORACLE_SID。在winnt不台， ORACLE_SID还需存在于注册表中。<br _extended="true" />
且ORACLE_SID必须与instance_name的值一致，否则，你将会收到一个错误，在unix平台，是&#8220;ORACLE not available&#8221;,在winnt平台，是&#8220;TNS:协议适配器错误&#8221;。</font></font></p>
<p _extended="true"><font face="宋体" _extended="true"><font size="3" _extended="true"><strong _extended="true">数据库实例名与网络连接</strong><br _extended="true" />
数据库实例名除了与操作系统交互外，还用于网络连接的oracle服务器标识。当你配置oracle主机连接串的时候，就需要指定实例名。当然8i以后版本的网络组件要求使用的是服务名SERVICE_NAME。这个概念接下来说明。</font></font></p>
<p _extended="true"><font face="宋体" _extended="true"><font size="3" _extended="true"><strong _extended="true"><span style="color: red" _extended="true"><font face="宋体" _extended="true"><font size="3" _extended="true"><strong _extended="true">三、数据库域名<br _extended="true" />
<br _extended="true" />
</strong></font></font></span>什么是数据库域名？</strong><br _extended="true" />
在分布工数据库系统中，不同版本的数据库服务器之间，不论运行的操作系统是unix或是windows，各服务器之间都可以通过数据库链路进行远程复制，数据库域名主要用于oracle分布式环境中的复制。举例说明如：<br _extended="true" />
全国交通运政系统的分布式数据库，其中：<br _extended="true" />
福建节点： fj.jtyz<br _extended="true" />
福建厦门节点： xm.fj.jtyz<br _extended="true" />
江西： jx.jtyz<br _extended="true" />
江西上饶：sr.jx.jtyz<br _extended="true" />
这就是数据库域名。<br _extended="true" />
数据库域名在存在于参数文件中，他的参数是db_domain.</font></font></p>
<p _extended="true"><font face="宋体" _extended="true"><font size="3" _extended="true"><strong _extended="true">查询数据库域名</strong><br _extended="true" />
方法一：select value from v$parameter where name = 'db_domain';<br _extended="true" />
方法二：show parameter domain<br _extended="true" />
方法三：在参数文件中查询。</font></font></p>
<p _extended="true"><font face="宋体" _extended="true"><font size="3" _extended="true"><strong _extended="true">全局数据库名</strong><br _extended="true" />
全局数据库名=数据库名+数据库域名，如前述福建节点的全局数据库名是：oradb.fj.jtyz</font></font></p>
<p _extended="true"><font face="宋体" _extended="true"><font size="3" _extended="true"><strong style="color: red" _extended="true">四、数据库服务名<br _extended="true" />
</strong><br _extended="true" />
</font></font><font face="宋体" _extended="true"><font size="3" _extended="true"><strong _extended="true">什么是数据库服务名？<br _extended="true" />
</strong>从oracle9i版本开始，引入了一个新的参数，即数据库服务名。参数名是SERVICE_NAME。<br _extended="true" />
如果数据库有域名，则数据库服务名就是全局数据库名；否则，数据库服务名与数据库名相同。</font></font></p>
<p _extended="true"><font face="宋体" _extended="true"><font size="3" _extended="true"><strong _extended="true">查询数据库服务名</strong><br _extended="true" />
方法一：select value from v$parameter where name = 'service_name';<br _extended="true" />
方法二：show parameter service_name<br _extended="true" />
方法三：在参数文件中查询。</font></font></p>
<p _extended="true"><font face="宋体" _extended="true"><font size="3" _extended="true"><strong _extended="true">数据库服务名与网络连接<br _extended="true" />
</strong>从oracle8i开如的oracle网络组件，数据库与客户端的连接主机串使用数据库服务名。之前用的是ORACLE_SID,即数据库实例名。</font></font></p>
<img src ="http://www.blogjava.net/jesenblog/aggbug/188259.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jesenblog/" target="_blank">白露</a> 2008-03-24 15:32 <a href="http://www.blogjava.net/jesenblog/articles/188259.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Oracle中password file的作用及说明  </title><link>http://www.blogjava.net/jesenblog/articles/188257.html</link><dc:creator>白露</dc:creator><author>白露</author><pubDate>Mon, 24 Mar 2008 07:30:00 GMT</pubDate><guid>http://www.blogjava.net/jesenblog/articles/188257.html</guid><wfw:comment>http://www.blogjava.net/jesenblog/comments/188257.html</wfw:comment><comments>http://www.blogjava.net/jesenblog/articles/188257.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jesenblog/comments/commentRss/188257.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jesenblog/services/trackbacks/188257.html</trackback:ping><description><![CDATA[<p _extended="true"><font face="宋体" _extended="true">在数据库没有启动之前，数据库内建用户是无法通过数据库来验证身份的</font></p>
<p _extended="true"><font face="宋体" _extended="true">口令文件中存放sysdba/sysoper用户的用户名及口令<br _extended="true" />
允许用户通过口令文件验证，在数据库未启动之前登陆<br _extended="true" />
从而启动数据库</font></p>
<p _extended="true"><font face="宋体" _extended="true">如果没有口令文件，在数据库未启动之前就只能通过操作系统认证.</font></p>
<p _extended="true"><font face="宋体" _extended="true">使用Rman，很多时候需要在nomount,mount等状态对数据库进行处理<br _extended="true" />
所以通常要求sysdba权限如果属于本地DBA组，可以通过操作系统认证登陆<br _extended="true" />
如果是远程sysdba登陆，需要通过passwordfile认证.</font></p>
<p _extended="true"><font face="宋体" _extended="true">1.remote_login_passwordfile = NONE</font></p>
<p _extended="true"><font face="宋体" _extended="true">此时停用口令文件验证，Oracle数据库不允许远程SYSDBA/SYSOPER身份登录<br _extended="true" />
无法通过远程进行数据库起停等操作管理</font></p>
<p _extended="true"><font face="宋体" _extended="true">local:</font></p>
<p _extended="true"><font face="宋体" _extended="true"><br _extended="true" />
&nbsp;</font></p>
<p _extended="true">[oracle@jumper oracle]$ sqlplus "/ as sysdba"</p>
<p _extended="true">SQL*Plus: Release 9.2.0.3.0 - Production on Thu Apr 15 09:58:45 2004</p>
<p _extended="true">Copyright (c) 1982, 2002, Oracle Corporation. All rights reserved.</p>
<p _extended="true"><br _extended="true" />
Connected to:<br _extended="true" />
Oracle9i Enterprise Edition Release 9.2.0.3.0 - Production<br _extended="true" />
With the Partitioning, OLAP and Oracle Data Mining options<br _extended="true" />
JServer Release 9.2.0.3.0 - Production</p>
<p _extended="true">SQL&gt; alter user sys identified by oracle;</p>
<p _extended="true">User altered.</p>
<p _extended="true">SQL&gt; show parameter pass</p>
<p _extended="true">NAME&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; TYPE&nbsp;&nbsp; VALUE<br _extended="true" />
--------------------- ----------- ------------------------------<br _extended="true" />
remote_login_passwordfile string NONE<br _extended="true" />
&nbsp;&nbsp;<br _extended="true" />
&nbsp;&nbsp;&nbsp;</p>
<p _extended="true">remote:</p>
<p _extended="true"><br _extended="true" />
&nbsp;</p>
<p _extended="true">E:\Oracle\ora92\bin&gt;sqlplus /nologSQL*Plus: Release 9.2.0.4.0 -<br _extended="true" />
Production on 星期四 4月 15 09:39:22 2004Copyright (c) 1982, 2002, Oracle<br _extended="true" />
Corporation. All rights reserved.SQL&gt; connect sys/oracle@hsjf as<br _extended="true" />
sysdbaERROR:ORA-01017: invalid username/password; logon denied</p>
<p _extended="true">此处实际上是无法通过口令文件验证</p>
<p _extended="true">2.remote_login_passwordfile = exclusive</p>
<p _extended="true"><br _extended="true" />
&nbsp;</p>
<p _extended="true">&nbsp;</p>
<p _extended="true">&nbsp;</p>
<p _extended="true">SQL&gt; alter system set remote_login_passwordfile=exclusive scope=spfile;</p>
<p _extended="true">System altered.</p>
<p _extended="true">SQL&gt; startup force;<br _extended="true" />
ORACLE instance started.</p>
<p _extended="true">Total System Global Area 131142648 bytes<br _extended="true" />
Fixed Size 451576 bytes<br _extended="true" />
Variable Size 104857600 bytes<br _extended="true" />
Database Buffers 25165824 bytes<br _extended="true" />
Redo Buffers 667648 bytes<br _extended="true" />
Database mounted.<br _extended="true" />
Database opened.<br _extended="true" />
SQL&gt; show parameter pass</p>
<p _extended="true">NAME TYPE VALUE<br _extended="true" />
------------------------------------ ----------- ------------------------------<br _extended="true" />
remote_login_passwordfile string EXCLUSIVE<br _extended="true" />
SQL&gt; alter user sys identified by oracle;</p>
<p _extended="true">User altered.</p>
<p _extended="true">&nbsp;</p>
<p _extended="true">remote:</p>
<p _extended="true">&nbsp;</p>
<p _extended="true">&nbsp;</p>
<p _extended="true">E:\Oracle\ora92\bin&gt;sqlplus /nologSQL*Plus: Release 9.2.0.4.0 -<br _extended="true" />
Production on 星期四 4月 15 09:47:11 2004Copyright (c) 1982, 2002, Oracle<br _extended="true" />
Corporation. All rights reserved.SQL&gt; connect sys/oracle@hsjf as<br _extended="true" />
sysdba已连接。SQL&gt; show userUSER 为"SYS"SQL&gt;</p>
<p _extended="true">&nbsp;</p>
<p _extended="true">这实际上就是通过口令文件验证登录的</p>
<p _extended="true">3.进一步测试</p>
<p _extended="true">如果此时我们删除passwdfile,sysdba/sysoper将无法认证，也就无法登陆数据库</p>
<p _extended="true"><br _extended="true" />
Server:</p>
<p _extended="true">&nbsp;</p>
<p _extended="true">SQL&gt; !<br _extended="true" />
[oracle@jumper oracle]$ cd $ORACLE_HOME/dbs<br _extended="true" />
[oracle@jumper dbs]$ ls orapwhsjf<br _extended="true" />
orapwhsjf<br _extended="true" />
[oracle@jumper dbs]$ mv orapwhsjf orapwhsjf.bak<br _extended="true" />
[oracle@jumper dbs]$</p>
<p _extended="true"><br _extended="true" />
&nbsp;</p>
<p _extended="true">&nbsp;</p>
<p _extended="true">Remote:</p>
<p _extended="true"><br _extended="true" />
&nbsp;</p>
<p _extended="true">E:\Oracle\ora92\bin&gt;sqlplus /nolog</p>
<p _extended="true">SQL*Plus: Release 9.2.0.4.0 - Production on 星期四 4月 15 09:50:14 2004</p>
<p _extended="true">Copyright (c) 1982, 2002, Oracle Corporation. All rights reserved.</p>
<p _extended="true">SQL&gt; connect sys/oracle@hsjf as sysdba<br _extended="true" />
ERROR:<br _extended="true" />
ORA-01031: insufficient privileges</p>
<p _extended="true"><br _extended="true" />
SQL&gt;</p>
<p _extended="true"><br _extended="true" />
&nbsp;</p>
<p _extended="true">&nbsp;</p>
<p _extended="true">这实际上就是无法通过口令文件验证身份</p>
<p _extended="true">&nbsp;</p>
<p _extended="true">4.如果丢失了passwdfile</p>
<p _extended="true">如果使用passwdfile却意外丢失，此时将不能启动数据库</p>
<p _extended="true">&nbsp;</p>
<p _extended="true">&nbsp;</p>
<p _extended="true">SQL&gt; startup force;<br _extended="true" />
ORACLE instance started.</p>
<p _extended="true">Total System Global Area 131142648 bytes<br _extended="true" />
Fixed Size 451576 bytes<br _extended="true" />
Variable Size 104857600 bytes<br _extended="true" />
Database Buffers 25165824 bytes<br _extended="true" />
Redo Buffers 667648 bytes<br _extended="true" />
ORA-01990: error opening password file '/opt/oracle/product/9.2.0/dbs/orapw'<br _extended="true" />
ORA-27037: unable to obtain file status<br _extended="true" />
Linux Error: 2: No such file or directory<br _extended="true" />
Additional information: 3</p>
<p _extended="true">&nbsp;</p>
<p _extended="true">&nbsp;</p>
<p _extended="true">&nbsp;</p>
<p _extended="true">此时可以通过orapwd重建口令文件来解决<br _extended="true" />
此处我们恢复口令文件既可</p>
<p _extended="true"><br _extended="true" />
&nbsp;</p>
<p _extended="true">SQL&gt; !<br _extended="true" />
[oracle@jumper oracle]$ mv $ORACLE_HOME/dbs/orapwhsjf.bak orapwhsjf<br _extended="true" />
[oracle@jumper oracle]$ exit<br _extended="true" />
exit</p>
<p _extended="true">SQL&gt; alter database open;</p>
<p _extended="true">Database altered.</p>
<p _extended="true">SQL&gt;</p>
<p _extended="true">&nbsp;</p>
<p _extended="true">&nbsp;</p>
<p _extended="true">&nbsp;</p>
<p _extended="true"><br _extended="true" />
大致就是如此.</p>
<p _extended="true">&nbsp;</p>
<p _extended="true">5. remote_login_passwordfile = shared</p>
<p _extended="true">我们看一下Oracle9i文档中的说明:</p>
<p _extended="true">SHARED</p>
<p _extended="true">More than one database can use a password file. However, the only user recognized by the password file is SYS.</p>
<p _extended="true"><br _extended="true" />
意思是说多个数据库可以共享一个口令文件,但是只可以识别一个用户:SYS</p>
<p _extended="true">&nbsp;</p>
<p _extended="true">SQL&gt; select * from v$pwfile_users;</p>
<p _extended="true">USERNAME SYSDB SYSOP<br _extended="true" />
------------------------------ ----- -----<br _extended="true" />
SYS TRUE TRUE</p>
<p _extended="true">SQL&gt; grant sysdba to eygle;<br _extended="true" />
grant sysdba to eygle<br _extended="true" />
*<br _extended="true" />
ERROR at line 1:<br _extended="true" />
ORA-01994: GRANT failed: cannot add users to public password file</p>
<p _extended="true"><br _extended="true" />
SQL&gt; show parameter password</p>
<p _extended="true">NAME TYPE VALUE<br _extended="true" />
------------------------------------ ----------- ------------------------------<br _extended="true" />
remote_login_passwordfile string SHARED</p>
<p _extended="true">&nbsp;</p>
<p _extended="true">&nbsp;</p>
<p _extended="true">我们看到,此时的口令文件中是不能添加用户的.</p>
<p _extended="true">很多人的疑问在于:口令文件的缺省名称是orapw&lt;sid&gt;,怎么能够共享?</p>
<p _extended="true">实际上是这样的: Oracle数据库在启动时,首先查找的是orapw&lt;sid&gt;的口令文件,如果该文件不存在,则开始查找,orapw的口令文件<br _extended="true" />
如果口令文件命名为orapw,多个数据库就可以共享.</p>
<p _extended="true">我们看一下测试:</p>
<p _extended="true">&nbsp;</p>
<p _extended="true">[oracle@jumper dbs]$ sqlplus "/ as sysdba"</p>
<p _extended="true">SQL*Plus: Release 9.2.0.3.0 - Production on Tue Jul 6 09:40:34 2004</p>
<p _extended="true">Copyright (c) 1982, 2002, Oracle Corporation.&nbsp; All rights reserved.</p>
<p _extended="true"><br _extended="true" />
Connected to:<br _extended="true" />
Oracle9i Enterprise Edition Release 9.2.0.3.0 - Production<br _extended="true" />
With the Partitioning, OLAP and Oracle Data Mining options<br _extended="true" />
JServer Release 9.2.0.3.0 - Production</p>
<p _extended="true">SQL&gt; shutdown immediate<br _extended="true" />
Database closed.<br _extended="true" />
Database dismounted.<br _extended="true" />
ORACLE instance shut down.<br _extended="true" />
SQL&gt; !<br _extended="true" />
[oracle@jumper dbs]$ ls<br _extended="true" />
hsjf&nbsp; initdw.ora&nbsp; inithsjf.ora&nbsp; init.ora&nbsp; lkHSJF&nbsp; orapwhsjf&nbsp; spfilehsjf.ora<br _extended="true" />
[oracle@jumper dbs]$ mv orapwhsjf orapwhsjf.bak<br _extended="true" />
[oracle@jumper dbs]$ exit<br _extended="true" />
exit</p>
<p _extended="true">SQL&gt; startup<br _extended="true" />
ORACLE instance started.</p>
<p _extended="true">Total System Global Area&nbsp; 235999908 bytes<br _extended="true" />
Fixed Size&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 451236 bytes<br _extended="true" />
Variable Size&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 201326592 bytes<br _extended="true" />
Database Buffers&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 33554432 bytes<br _extended="true" />
Redo Buffers&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 667648 bytes<br _extended="true" />
ORA-01990: error opening password file '/opt/oracle/product/9.2.0/dbs/orapw'--这是最后查找的文件<br _extended="true" />
ORA-27037: unable to obtain file status<br _extended="true" />
Linux Error: 2: No such file or directory<br _extended="true" />
Additional information: 3</p>
<p _extended="true">&nbsp;&nbsp;&nbsp;</p>
<p _extended="true">&nbsp;</p>
<p _extended="true">我们建立orapw口令文件,这时候可以打开数据库.</p>
<p _extended="true">SQL&gt; !<br _extended="true" />
[oracle@jumper dbs]$ ls<br _extended="true" />
hsjf&nbsp; initdw.ora&nbsp; inithsjf.ora&nbsp; init.ora&nbsp; lkHSJF&nbsp; orapwhsjf.bak&nbsp; spfilehsjf.ora<br _extended="true" />
[oracle@jumper dbs]$ cp orapwhsjf.bak orapw<br _extended="true" />
[oracle@jumper dbs]$ exit<br _extended="true" />
exit</p>
<p _extended="true">SQL&gt; alter database open;</p>
<p _extended="true">Database altered.</p>
<p _extended="true">SQL&gt; show parameter passw</p>
<p _extended="true">NAME&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; TYPE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; VALUE<br _extended="true" />
------------------------------------ ----------- ------------------------------<br _extended="true" />
remote_login_passwordfile&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; string&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SHARED<br _extended="true" />
SQL&gt;&nbsp;&nbsp;&nbsp;&nbsp;<br _extended="true" />
&nbsp;</p>
<p _extended="true">那么你可能会有这样的疑问,多个Exclusive的数据库是否可以共享一个口令文件(orapw)呢?</p>
<p _extended="true">我们继续这个实验:</p>
<p _extended="true">SQL&gt; show parameter passwordNAME TYPE VALUE<br _extended="true" />
------------------------------------ ----------- ------------------------------<br _extended="true" />
remote_login_passwordfile string SHARED</p>
<p _extended="true"><br _extended="true" />
[oracle@jumper dbs]$ strings orapw<br _extended="true" />
]\[Z<br _extended="true" />
ORACLE Remote Password file<br _extended="true" />
INTERNAL<br _extended="true" />
AB27B53EDC5FEF41<br _extended="true" />
8A8F025737A9097A<br _extended="true" />
&nbsp;</p>
<p _extended="true">注意这里仅记录着INTERNAL/SYS的口令</p>
<p _extended="true">REMOTE_LOGIN_PASSWORDFILE=EXCLUSIVE 时</p>
<p _extended="true">SQL&gt; alter system set remote_login_passwordfile=exclusive scope=spfile;System altered.</p>
<p _extended="true">SQL&gt; startup force;<br _extended="true" />
ORACLE instance started.</p>
<p _extended="true">Total System Global Area 235999908 bytes<br _extended="true" />
Fixed Size 451236 bytes<br _extended="true" />
Variable Size 201326592 bytes<br _extended="true" />
Database Buffers 33554432 bytes<br _extended="true" />
Redo Buffers 667648 bytes<br _extended="true" />
Database mounted.<br _extended="true" />
Database opened.<br _extended="true" />
SQL&gt; !</p>
<p _extended="true">[oracle@jumper bin]$ cd $ORACLE_HOME/dbs<br _extended="true" />
[oracle@jumper dbs]$ strings orapw<br _extended="true" />
]\[Z<br _extended="true" />
ORACLE Remote Password file<br _extended="true" />
HSJF<br _extended="true" />
INTERNAL<br _extended="true" />
AB27B53EDC5FEF41<br _extended="true" />
8A8F025737A9097A<br _extended="true" />
[oracle@jumper dbs]$ exit<br _extended="true" />
exit<br _extended="true" />
&nbsp;</p>
<p _extended="true">注意这里,以EXCLUSIVE 方式启动以后,实例名称信息被写入口令文件.</p>
<p _extended="true">此时如果有其他实例以Exclusive模式启动仍然可以使用这个口令文件,口令文件中的实例名称同时被改写.</p>
<p _extended="true">也就是说,数据库只在启动过程中才读取口令文件,数据库运行过程中并不锁定该文件,类似于pfile/spfile文件.</p>
<p _extended="true"><br _extended="true" />
SQL&gt; select * from v$pwfile_users;USERNAME SYSDB SYSOP<br _extended="true" />
------------------------------ ----- -----<br _extended="true" />
SYS TRUE TRUE</p>
<p _extended="true">SQL&gt; grant sysdba to eygle;</p>
<p _extended="true">Grant succeeded.</p>
<p _extended="true">SQL&gt; select * from v$pwfile_users;</p>
<p _extended="true">USERNAME SYSDB SYSOP<br _extended="true" />
------------------------------ ----- -----<br _extended="true" />
SYS TRUE TRUE<br _extended="true" />
EYGLE TRUE FALSE</p>
<p _extended="true">SQL&gt; !<br _extended="true" />
[oracle@jumper bin]$ cd $ORACLE_HOME/dbs<br _extended="true" />
[oracle@jumper dbs]$ strings orapw<br _extended="true" />
]\[Z<br _extended="true" />
ORACLE Remote Password file<br _extended="true" />
HSJF<br _extended="true" />
INTERNAL<br _extended="true" />
AB27B53EDC5FEF41<br _extended="true" />
8A8F025737A9097A<br _extended="true" />
&gt;EYGLE<br _extended="true" />
B726E09FE21F8E83<br _extended="true" />
&nbsp;</p>
<p _extended="true"><br _extended="true" />
注意此时可以增加SYSDBA用户，并且这些信息可以被写入到口令文件.</p>
<p _extended="true">一旦口令文件中增加了其他SYSDBA用户,此文件不再能够被其他Exclusive的实例共享.</p>
<p _extended="true"><br _extended="true" />
实际上，口令文件对于其他用户来说就是启到了一个 sudo 的作用.</p>
<p _extended="true">6.重建口令文件</p>
<p _extended="true">如果口令文件丢失,可以使用orapwd可以重建口令文件，语法如下:</p>
<p _extended="true">[oracle@jumper oracle]$ orapwdUsage: orapwd file=&lt;fname&gt; password=&lt;password&gt; entries=&lt;users&gt; where<br _extended="true" />
file - name of password file (mand),<br _extended="true" />
password - password for SYS (mand),<br _extended="true" />
entries - maximum number of distinct DBA and OPERs (opt),<br _extended="true" />
There are no spaces around the equal-to (=) character.</p>
<div class="invisible" id="reference" _extended="true">文章引用自：<a href=" _extended=" target="true"  ?></a> </div>
<img src ="http://www.blogjava.net/jesenblog/aggbug/188257.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jesenblog/" target="_blank">白露</a> 2008-03-24 15:30 <a href="http://www.blogjava.net/jesenblog/articles/188257.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>变异表</title><link>http://www.blogjava.net/jesenblog/articles/188256.html</link><dc:creator>白露</dc:creator><author>白露</author><pubDate>Mon, 24 Mar 2008 07:28:00 GMT</pubDate><guid>http://www.blogjava.net/jesenblog/articles/188256.html</guid><wfw:comment>http://www.blogjava.net/jesenblog/comments/188256.html</wfw:comment><comments>http://www.blogjava.net/jesenblog/articles/188256.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jesenblog/comments/commentRss/188256.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jesenblog/services/trackbacks/188256.html</trackback:ping><description><![CDATA[变异表就是当前正被DML语句更新的表<br _extended="true" />
<br _extended="true" />
为了更好的阐述变异表考虑下面3个表：students,classes,registered_students 表students和classes都没有依赖关系但是表registered_students有两个外键一个依赖于students表的主键一个依赖于classes的主键表如下：<br _extended="true" />
<br _extended="true" />
create table students (<br _extended="true" />
&nbsp;&nbsp;id&nbsp; &nbsp;number(5) not null,<br _extended="true" />
&nbsp;&nbsp;current_credits&nbsp; &nbsp;number(3),<br _extended="true" />
&nbsp;&nbsp;major&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; varchar2(20),<br _extended="true" />
&nbsp;&nbsp;last_name&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;varchar2(20) not null,<br _extended="true" />
&nbsp;&nbsp;first_name&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;varchar2(20) not null,<br _extended="true" />
&nbsp;&nbsp;middle_initial&nbsp; &nbsp; varchar2(20) not null,<br _extended="true" />
&nbsp;&nbsp;constraint students_pk primary key (id));<br _extended="true" />
<br _extended="true" />
create table classes (<br _extended="true" />
&nbsp;&nbsp;department&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;char(3) not null,<br _extended="true" />
&nbsp;&nbsp;course&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;number(3) not null,<br _extended="true" />
&nbsp;&nbsp;current_students&nbsp;&nbsp;number(3) not null,<br _extended="true" />
&nbsp;&nbsp;num_credits&nbsp; &nbsp;&nbsp; &nbsp; number(1) not null,<br _extended="true" />
&nbsp;&nbsp;name&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;varchar2(30) not null,<br _extended="true" />
&nbsp;&nbsp;constraint classes_pk primary key (department,course));<br _extended="true" />
<br _extended="true" />
create table registered_students (<br _extended="true" />
&nbsp;&nbsp;student_id&nbsp;&nbsp;number(5) not null,<br _extended="true" />
&nbsp;&nbsp;department&nbsp;&nbsp;char(3)&nbsp; &nbsp;not null,<br _extended="true" />
&nbsp;&nbsp;course&nbsp; &nbsp;&nbsp; &nbsp;number(3) not null,<br _extended="true" />
&nbsp;&nbsp;grade&nbsp; &nbsp;&nbsp; &nbsp; char(1),<br _extended="true" />
&nbsp;&nbsp;constraint rs_grade check (grade in ('a,','b','c','d','f')),<br _extended="true" />
&nbsp;&nbsp;constraint re_student_id foreign key&nbsp;&nbsp;(student_id) references students (id),<br _extended="true" />
&nbsp;&nbsp;constraint re_department_course foregn key (department,course) references classes (department,course));<br _extended="true" />
<br _extended="true" />
表registered_students 上声明了2个引用完整性约束，因此表students和classes都是registered_students 的约束表，由于存在这种约束所以表students和classes可能会需要使用DML语句进行更新和查询，另外在registered_students表上执行DML语句的时候它就变成一个变异表<br _extended="true" />
<br _extended="true" />
触发器中SQL语句不能：读取或更新触发语句的任何变异表也包括触发表本身，读取或更新该触发表的约束表的主键列、唯一性键列或外键列但是如果需要也可以更新其他列。这些限制约束适用于所有行级触发器。但有个特例就是如果INSERT只影响一行记录那么定义在这行上的行级BEFORE和AFTER触发器就不会将这个触发表当作变异表。<br _extended="true" />
<br _extended="true" />
作为实例可以考虑下面这个触发器即使他更新了students和classes这两个表但是依然是合法的因为更新的列都不是主键列<br _extended="true" />
<br _extended="true" />
create or replace trigger cascadersinserts<br _extended="true" />
&nbsp;&nbsp;before insert on registered_students<br _extended="true" />
&nbsp;&nbsp;for each row<br _extended="true" />
declare<br _extended="true" />
&nbsp;&nbsp;v_credits&nbsp;&nbsp;classes.num_credits%type;<br _extended="true" />
begin<br _extended="true" />
&nbsp;&nbsp;select num_credits into v_credits from classes where department=:new.department and course=:new.course;<br _extended="true" />
&nbsp;&nbsp;update students set current_credits=current_credits+v_credits where id=:new.student_id;<br _extended="true" />
&nbsp;&nbsp;update classes set current_students=current_students+1 where department=:new.department and course=:new.course;<br _extended="true" />
end cascadersinserts;<br _extended="true" />
<br _extended="true" />
变异表示例<br _extended="true" />
<br _extended="true" />
假定希望将每一门主修课程的学生人数限制在5人，可以在students表上定义一个行级触发器来实现这个任务<br _extended="true" />
<br _extended="true" />
create or replace trigger limitmajors<br _extended="true" />
&nbsp;&nbsp;before insert or update of major on students<br _extended="true" />
&nbsp;&nbsp;for each row<br _extended="true" />
declare<br _extended="true" />
&nbsp;&nbsp;v_maxstudents constant number:=5;<br _extended="true" />
&nbsp;&nbsp;v_currentstudents number;<br _extended="true" />
begin<br _extended="true" />
&nbsp;&nbsp;select count(*) into v_currentstudents from students where major=:new.major;<br _extended="true" />
&nbsp;&nbsp;if v_currentstudents+1&gt;v_maxstudents then<br _extended="true" />
&nbsp; &nbsp;&nbsp;&nbsp;raise_application_error(-20000,'too many students in major'||:new.major);<br _extended="true" />
&nbsp;&nbsp;end if;<br _extended="true" />
end limitmajors;<br _extended="true" />
<br _extended="true" />
初看之下似乎实现了这个目标但是会产生错误原因是触发器查询了它自己的触发表而该触发表又是一个变异表<br _extended="true" />
<br _extended="true" />
那么要想实现就意味这不能在行级触发器里查询该表，但是可以在语句级触发器里查询它。但是不能简单的将它设计成一个语句级触发器因为我们需要在触发器主体中使用:new.major的值。这个问题的解决办法就是创建2个触发器一个行级的一个语句的，在行级里记录:new.major的值但是不查询表，查询在语句里实现。那么怎么记录值呢，就要通过一个包了。<br _extended="true" />
<br _extended="true" />
create or replace package studentdata as<br _extended="true" />
&nbsp;&nbsp;type t_majors is table of students.major%type index by binary_integer;<br _extended="true" />
&nbsp;&nbsp;type t_ids is table of students.id%type index by binary<br _extended="true" />
&nbsp;&nbsp;v_studentmajors t_majors;<br _extended="true" />
&nbsp;&nbsp;v_studentids&nbsp; &nbsp; t_ids;<br _extended="true" />
&nbsp;&nbsp;v_numbertries&nbsp; &nbsp;binary_integer:=0;<br _extended="true" />
end studentsdata;<br _extended="true" />
<br _extended="true" />
create or replace trigger rlimitmajors<br _extended="true" />
&nbsp;&nbsp;before insert or update of major on students<br _extended="true" />
&nbsp;&nbsp;for each row<br _extended="true" />
begin<br _extended="true" />
&nbsp;&nbsp;studentdata.v_numbertries:=studentdata.v_numbertries+1;<br _extended="true" />
&nbsp;&nbsp;studentdata.v_studentmajors(studentdata.v_numberies):=:new.major;<br _extended="true" />
&nbsp;&nbsp;studentdata.v_studentids(studentdata.v_numberies):=:new.id;<br _extended="true" />
end rlimitmajors;<br _extended="true" />
<br _extended="true" />
create or replace trigger slimitmajors<br _extended="true" />
&nbsp;&nbsp;after insert or update of major on students<br _extended="true" />
declare<br _extended="true" />
&nbsp;&nbsp;v_maxstudents constant number:=2;<br _extended="true" />
&nbsp;&nbsp;v_currentstudents number;<br _extended="true" />
&nbsp;&nbsp;v_studentid student.id%type;<br _extended="true" />
&nbsp;&nbsp;v_major students.major%type;<br _extended="true" />
begin<br _extended="true" />
&nbsp;&nbsp;for v_loopindex in 1..studentdata.v_numberies loop<br _extended="true" />
&nbsp; &nbsp;&nbsp; &nbsp;v_studentid:=studentdata.v_studentids(v_loopindex);<br _extended="true" />
&nbsp; &nbsp;&nbsp; &nbsp;v_major:=studentdata.v_studentmajors(v_loopindex);<br _extended="true" />
&nbsp;&nbsp;select count(*) into v_currentstudents from students where major=v_major;<br _extended="true" />
&nbsp;&nbsp;if v_currentstudents&gt;v_maxstudents then<br _extended="true" />
&nbsp; &nbsp;&nbsp;&nbsp;raise_application_error(-20000,'too many students for major '||v_major||'because of student'||v_studentid);<br _extended="true" />
&nbsp;&nbsp;end if;<br _extended="true" />
&nbsp;&nbsp;studentdata.v_numberies:=0;<br _extended="true" />
end slimitmajors;<br _extended="true" />
<br _extended="true" />
这样就得到了我们想要的结果了
<img src ="http://www.blogjava.net/jesenblog/aggbug/188256.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jesenblog/" target="_blank">白露</a> 2008-03-24 15:28 <a href="http://www.blogjava.net/jesenblog/articles/188256.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>oracle 异常处理  </title><link>http://www.blogjava.net/jesenblog/articles/188255.html</link><dc:creator>白露</dc:creator><author>白露</author><pubDate>Mon, 24 Mar 2008 07:27:00 GMT</pubDate><guid>http://www.blogjava.net/jesenblog/articles/188255.html</guid><wfw:comment>http://www.blogjava.net/jesenblog/comments/188255.html</wfw:comment><comments>http://www.blogjava.net/jesenblog/articles/188255.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jesenblog/comments/commentRss/188255.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jesenblog/services/trackbacks/188255.html</trackback:ping><description><![CDATA[&nbsp;1、 异常的优点<br _extended="true" />
如果没有异常，在程序中，应当检查每个命令的成功还是失败，如<br _extended="true" />
BEGIN<br _extended="true" />
SELECT ...<br _extended="true" />
-- check for &#8217;no data found&#8217; error<br _extended="true" />
SELECT ...<br _extended="true" />
-- check for &#8217;no data found&#8217; error<br _extended="true" />
SELECT ...<br _extended="true" />
-- check for &#8217;no data found&#8217; error<br _extended="true" />
这种实现的方法缺点在于错误处理没有与正常处理分开，可读性差，使用异常，可以方便处理错误，而且异常处理程序与正常的事务逻辑分开，提高了可读性，如<br _extended="true" />
BEGIN<br _extended="true" />
SELECT ...<br _extended="true" />
SELECT ...<br _extended="true" />
SELECT ...<br _extended="true" />
...<br _extended="true" />
EXCEPTION<br _extended="true" />
WHEN NO_DATA_FOUND THEN -- catches all &#8217;no data found&#8217; errors<br _extended="true" />
2、 异常的分类<br _extended="true" />
有两种类型的异常，一种为内部异常，一种为用户自定义异常，内部异常是执行期间返回到PL/SQL块的ORACLE错误或由PL/SQL代码的某操作引起的错误，如除数为零或内存溢出的情况。用户自定义异常由开发者显示定义，在PL/SQL块中传递信息以控制对于应用的错误处理。<br _extended="true" />
每当PL/SQL违背了ORACLE原则或超越了系统依赖的原则就会隐式的产生内部异常。因为每个ORACLE错误都有一个号码并且在PL/SQL中异常通过名字处理，ORACLE提供了预定义的内部异常。如SELECT INTO 语句不返回行时产生的ORACLE异常NO_DATA_FOUND。对于预定义异常，现将最常用的异常列举如下：<br _extended="true" />
exception oracle error sqlcode value condition<br _extended="true" />
no_data_found ora-01403 +100 select into 语句没有符合条件的记录返回<br _extended="true" />
too_mang_rows ora-01422 -1422 select into 语句符合条件的记录有多条返回<br _extended="true" />
dup_val_on_index ora-00001 -1 对于数据库表中的某一列，该列已经被限制为唯一索引，程序试图存储两个重复的值<br _extended="true" />
value_error ora-06502 -6502 在转换字符类型，截取或长度受限时，会发生该异常，如一个字符分配给一个变量，而该变量声明的长度比该字符短，就会引发该异常<br _extended="true" />
storage_error ora-06500 -6500 内存溢出<br _extended="true" />
zero_divide ora-01476 -1476 除数为零<br _extended="true" />
case_not_found ora-06592 -6530 对于选择case语句，没有与之相匹配的条件，同时，也没有else语句捕获其他的条件<br _extended="true" />
cursor_already_open ora-06511 -6511 程序试图打开一个已经打开的游标<br _extended="true" />
timeout_on_resource ora-00051 -51 系统在等待某一资源，时间超时<br _extended="true" />
如果要处理未命名的内部异常，必须使用OTHERS异常处理器或PRAGMA EXCEPTION_INIT 。PRAGMA由编译器控制，或者是对于编译器的注释。PRAGMA在编译时处理，而不是在运行时处理。EXCEPTION_INIT告诉编译器将异常名与ORACLE错误码结合起来，这样可以通过名字引用任意的内部异常，并且可以通过名字为异常编写一适当的异常处理器。<br _extended="true" />
在子程序中使用EXCEPTION_INIT的语法如下：<br _extended="true" />
PRAGMA EXCEPTION_INIT(exception_name, -Oracle_error_number);<br _extended="true" />
在该语法中，异常名是声明的异常，下例是其用法：<br _extended="true" />
DECLARE<br _extended="true" />
deadlock_detected EXCEPTION;<br _extended="true" />
PRAGMA EXCEPTION_INIT(deadlock_detected, -60);<br _extended="true" />
BEGIN<br _extended="true" />
... -- Some operation that causes an ORA-00060 error<br _extended="true" />
EXCEPTION<br _extended="true" />
WHEN deadlock_detected THEN<br _extended="true" />
-- handle the error<br _extended="true" />
END;<br _extended="true" />
对于用户自定义异常，只能在PL/SQL块中的声明部分声明异常，异常的名字由EXCEPTION关键字引入：<br _extended="true" />
reserved_loaned Exception<br _extended="true" />
产生异常后，控制传给了子程序的异常部分，将异常转向各自异常控制块，必须在代码中使用如下的结构处理错误：<br _extended="true" />
Exception<br _extended="true" />
When exception1 then<br _extended="true" />
Sequence of statements;<br _extended="true" />
When exception2 then<br _extended="true" />
Sequence of statements;<br _extended="true" />
When others then<br _extended="true" />
3、异常的抛出<br _extended="true" />
由三种方式抛出异常<br _extended="true" />
1． 通过PL/SQL运行时引擎<br _extended="true" />
2. 使用RAISE语句<br _extended="true" />
3. 调用RAISE_APPLICATION_ERROR存储过程<br _extended="true" />
　当数据库或PL/SQL在运行时发生错误时，一个异常被PL/SQL运行时引擎自动抛出。异常也可以通过RAISE语句抛出<br _extended="true" />
　　RAISE exception_name;<br _extended="true" />
　　显式抛出异常是程序员处理声明的异常的习惯用法，但RAISE不限于声明了的异常，它可以抛出任何任何异常。例如，你希望用TIMEOUT_ON_RESOURCE错误检测新的运行时异常处理器，你只需简单的在程序中使用下面的语句：<br _extended="true" />
　　RAISE TIMEOUT_ON_RESOUCE;<br _extended="true" />
比如下面一个订单输入的例子，若当订单小于库存数量，则抛出异常，并且捕获该异常，处理异常<br _extended="true" />
DECLARE<br _extended="true" />
inventory_too_low EXCEPTION;<br _extended="true" />
---其他声明语句<br _extended="true" />
BEGIN<br _extended="true" />
IF order_rec.qty&gt;inventory_rec.qty THEN<br _extended="true" />
RAISE inventory_too_low;<br _extended="true" />
END IF<br _extended="true" />
EXCEPTION<br _extended="true" />
WHEN inventory_too_low THEN<br _extended="true" />
order_rec.staus:='backordered';<br _extended="true" />
END;<br _extended="true" />
<br _extended="true" />
RAISE_APPLICATION_ERROR内建函数用于抛出一个异常并给异常赋予一个错误号以及错误信息。自定义异常的缺省错误号是+1,缺省信息是User_Defined_Exception。RAISE_APPLICATION_ERROR函数能够在pl/sql程序块的执行部分和异常部分调用，显式抛出带特殊错误号的命名异常。 Raise_application_error(error_number,message[,true,false]))<br _extended="true" />
　　错误号的范围是-20,000到-20,999。错误信息是文本字符串，最多为2048字节。TRUE和FALSE表示是添加(TRUE)进错误堆(ERROR STACK)还是覆盖(overwrite)错误堆(FALSE)。缺省情况下是FALSE。<br _extended="true" />
如下代码所示：<br _extended="true" />
IF product_not_found THEN<br _extended="true" />
　　RAISE_APPLICATION_ERROR(-20123,'Invald product code' TRUE);<br _extended="true" />
END IF;<br _extended="true" />
4、异常的处理<br _extended="true" />
PL/SQL程序块的异常部分包含了程序处理错误的代码，当异常被抛出时，一个异常陷阱就自动发生，程序控制离开执行部分转入异常部分,一旦程序进入异常部分就不能再回到同一块的执行部分。下面是异常部分的一般语法：<br _extended="true" />
EXCEPTION<br _extended="true" />
　WHEN exception_name THEN<br _extended="true" />
　　Code for handing exception_name<br _extended="true" />
　[WHEN another_exception THEN<br _extended="true" />
　　Code for handing another_exception]<br _extended="true" />
　[WHEN others THEN<br _extended="true" />
　　code for handing any other exception.]<br _extended="true" />
用户必须在独立的WHEN子串中为每个异常设计异常处理代码，WHEN OTHERS子串必须放置在最后面作为缺省处理器处理没有显式处理的异常。当异常发生时，控制转到异常部分，ORACLE查找当前异常相应的WHEN..THEN语句，捕捉异常，THEN之后的代码被执行，如果错误陷阱代码只是退出相应的嵌套块，那么程序将继续执行内部块END后面的语句。如果没有找到相应的异常陷阱，那么将执行WHEN OTHERS。在异常部分WHEN 子串没有数量限制。<br _extended="true" />
EXCEPTION<br _extended="true" />
　WHEN inventory_too_low THEN<br _extended="true" />
　　order_rec.staus:='backordered';<br _extended="true" />
　　replenish_inventory(inventory_nbr=&gt;<br _extended="true" />
　　inventory_rec.sku,min_amount=&gt;order_rec.qty-inventory_rec.qty);<br _extended="true" />
　WHEN discontinued_item THEN<br _extended="true" />
　　--code for discontinued_item processing<br _extended="true" />
　WHEN zero_divide THEN<br _extended="true" />
　　--code for zero_divide<br _extended="true" />
　WHEN OTHERS THEN<br _extended="true" />
　　--code for any other exception<br _extended="true" />
END;<br _extended="true" />
当异常抛出后，控制无条件转到异常部分，这就意味着控制不能回到异常发生的位置，当异常被处理和解决后，控制返回到上一层执行部分的下一条语句。<br _extended="true" />
BEGIN<br _extended="true" />
　 DECLARE<br _extended="true" />
　　bad_credit exception;<br _extended="true" />
　 BEGIN<br _extended="true" />
　　RAISE bad_credit;<br _extended="true" />
　　　--发生异常，控制转向；<br _extended="true" />
　 EXCEPTION<br _extended="true" />
　　WHEN bad_credit THEN<br _extended="true" />
　　　dbms_output.put_line('bad_credit');<br _extended="true" />
　　END;<br _extended="true" />
　　--bad_credit异常处理后，控制转到这里<br _extended="true" />
　EXCEPTION<br _extended="true" />
　　WHEN OTHERS THEN<br _extended="true" />
　　　--控制不会从bad_credit异常转到这里<br _extended="true" />
　　　--因为bad_credit已被处理<br _extended="true" />
END;<br _extended="true" />
当异常发生时，在块的内部没有该异常处理器时，控制将转到或传播到上一层块的异常处理部分。<br _extended="true" />
BEGIN<br _extended="true" />
　 DECLARE ---内部块开始<br _extended="true" />
　　bad_credit exception;<br _extended="true" />
　 BEGIN<br _extended="true" />
　　RAISE bad_credit;<br _extended="true" />
　　　--发生异常，控制转向；<br _extended="true" />
　　EXCEPTION<br _extended="true" />
　　WHEN ZERO_DIVIDE THEN --不能处理bad_credite异常<br _extended="true" />
　　　dbms_output.put_line('divide by zero error');<br _extended="true" />
　　END --结束内部块<br _extended="true" />
　　　--控制不能到达这里，因为异常没有解决；<br _extended="true" />
　　　--异常部分<br _extended="true" />
　　EXCEPTION<br _extended="true" />
　　WHEN OTHERS THEN<br _extended="true" />
　　　--由于bad_credit没有解决，控制将转到这里<br _extended="true" />
END;<br _extended="true" />
5、异常的传播<br _extended="true" />
没有处理的异常将沿检测异常调用程序传播到外面，当异常被处理并解决或到达程序最外层传播停止。在声明部分抛出的异常将控制转到上一层的异常部分。<br _extended="true" />
BEGIN<br _extended="true" />
executable statements<br _extended="true" />
BEGIN<br _extended="true" />
today DATE:='SYADATE'; --ERRROR<br _extended="true" />
BEGIN --内部块开始<br _extended="true" />
dbms_output.put_line('this line will not execute');<br _extended="true" />
EXCEPTION<br _extended="true" />
WHEN OTHERS THEN<br _extended="true" />
--异常不会在这里处理<br _extended="true" />
END;--内部块结束<br _extended="true" />
EXCEPTION<br _extended="true" />
WHEN OTHERS THEN<br _extended="true" />
处理异常<br _extended="true" />
END<br _extended="true" />
执行部分抛出的异常将首先传递到同一块的异常部分，如果在同一块的异常部分没有处理这个异常的处理器，那么异常将会传播到上一层的异常部分中，一直到最外层。<br _extended="true" />
　　在异常部分抛出的异常将控制转到上一层的异常部分。<br _extended="true" />
　　另外错误报告函数SQLCODE和SQLERRM在OTHERS处理器中特别有用，因为它们返回ORACLE错误代码和消息。如下例所示：<br _extended="true" />
declare<br _extended="true" />
err_num NUMBER;<br _extended="true" />
err_msg VARCHAR2(100);<br _extended="true" />
BEGIN<br _extended="true" />
...<br _extended="true" />
EXCEPTION<br _extended="true" />
WHEN OTHERS THEN<br _extended="true" />
err_num := SQLCODE;<br _extended="true" />
err_msg := SUBSTR(SQLERRM, 1, 100);<br _extended="true" />
INSERT INTO errors VALUES (err_num, err_msg);<br _extended="true" />
END;<br _extended="true" />
<br _extended="true" />
&nbsp;<br _extended="true" />
<div style="border-bottom: #8ca6de 1px solid" align="right" _extended="true">2007-5-7 19:09:02&nbsp; &nbsp;</div>
<div class="inputcaption" style="border-bottom: #8ca6de 1px solid" _extended="true">
<table cellspacing="0" cellpadding="3" width="100%" border="0" _extended="true">
    <tbody _extended="true">
        <tr _extended="true">
            <td _extended="true"></td>
            <td align="right" _extended="true"><a href="http://www.delphibbs.com/keylife/iblog_comment.asp?xid=27962" _extended="true">查看评语&#187;&#187;&#187;</a>&nbsp; &nbsp;</td>
        </tr>
    </tbody>
</table>
</div>
<span class="inputcaption" style="height: 20px" _extended="true">&nbsp;2007-5-7 19:09:43&nbsp;</span> &nbsp; <span style="height: 20px" _extended="true">oracle 异常处理</span>
<p class="content" style="margin: 4px 2px 0px" _extended="true">~~~~有关于异常处理的3个知识点！<br _extended="true" />
<br _extended="true" />
1.EXCEPTION_INT编译指示<br _extended="true" />
功能是将某命名异常同某特定Oracle错误关联起来.<br _extended="true" />
主用用来捕捉某特定异常错误,而不是通过OTHERS来处理.<br _extended="true" />
语法:PROGMA EXCEPTION_INIT(exception_name,oracle_error_number)<br _extended="true" />
<br _extended="true" />
SQL&gt;<br _extended="true" />
SQL&gt; DECLARE<br _extended="true" />
&nbsp; 2 &nbsp; expa &nbsp; &nbsp;EXCEPTION;<br _extended="true" />
&nbsp; 3 &nbsp; PRAGMA &nbsp;EXCEPTION_INIT(expa,-6502);<br _extended="true" />
&nbsp; 4 &nbsp; vn &nbsp; &nbsp; &nbsp;NUMBER(1);<br _extended="true" />
&nbsp; 5 &nbsp;BEGIN<br _extended="true" />
&nbsp; 6 &nbsp; vn:=24;<br _extended="true" />
&nbsp; 7 &nbsp;EXCEPTION<br _extended="true" />
&nbsp; 8 &nbsp; WHEN expa THEN<br _extended="true" />
&nbsp; 9 &nbsp; &nbsp; dbms_output.put_line('数字或值错误 : &nbsp;数值精度太高');<br _extended="true" />
10 &nbsp; WHEN OTHERS THEN<br _extended="true" />
11 &nbsp; &nbsp; dbms_output.put_line(SQLCODE);<br _extended="true" />
12 &nbsp; &nbsp; dbms_output.put_line(substr(SQLERRM,1,100));<br _extended="true" />
13 &nbsp;END;<br _extended="true" />
14 &nbsp;/<br _extended="true" />
数字或值错误 : &nbsp;数值精度太高<br _extended="true" />
<br _extended="true" />
PL/SQL procedure successfully completed<br _extended="true" />
<br _extended="true" />
SQL&gt;<br _extended="true" />
<br _extended="true" />
2.RAISE_APPLICATION_ERROR<br _extended="true" />
功能用来自定义错误消息<br _extended="true" />
语法: RAISE_APPLICATION_ERROR(error_number,error_message,[keep_errors])<br _extended="true" />
error_number:-20 000到-20 999之间的值<br _extended="true" />
error_message:必须少于512个字符<br _extended="true" />
keep_errors:布尔值.为真则新的错误将被加到已存在的错误清单中（如果已存在的话），为假（默认值）则新的错误将代替当前的错误清单.<br _extended="true" />
<br _extended="true" />
SQL&gt; BEGIN<br _extended="true" />
&nbsp; 2 &nbsp; UPDATE t SET a='TEST' WHERE a='12345';<br _extended="true" />
&nbsp; 3 &nbsp; IF SQL%NOTFOUND THEN<br _extended="true" />
&nbsp; 4 &nbsp; &nbsp;raise_application_error(-20001,'你傻了？知道没有这样的数据还去更新！');<br _extended="true" />
&nbsp; 5 &nbsp; END IF;<br _extended="true" />
&nbsp; 6 &nbsp;EXCEPTION<br _extended="true" />
&nbsp; 7 &nbsp; WHEN OTHERS THEN<br _extended="true" />
&nbsp; 8 &nbsp; &nbsp;dbms_output.put_line(substr(SQLERRM,1,100));<br _extended="true" />
&nbsp; 9 &nbsp;END;<br _extended="true" />
10 &nbsp;/<br _extended="true" />
ORA-20001: 你傻了？知道没有这样的数据还去更新！<br _extended="true" />
<br _extended="true" />
PL/SQL procedure successfully completed<br _extended="true" />
<br _extended="true" />
SQL&gt;<br _extended="true" />
<br _extended="true" />
3.异常传播<br _extended="true" />
<br _extended="true" />
A可执行部分发生的异常<br _extended="true" />
1)如果当前语句块有该异常的处理程序则执行之，控制权交由外层语句块.<br _extended="true" />
<br _extended="true" />
当前语句块有该异常的处理程序:<br _extended="true" />
SQL&gt; DECLARE<br _extended="true" />
&nbsp; 2 &nbsp; expa EXCEPTION;<br _extended="true" />
&nbsp; 3 &nbsp; expb EXCEPTION;<br _extended="true" />
&nbsp; 4 &nbsp;BEGIN<br _extended="true" />
&nbsp; 5 &nbsp; BEGIN<br _extended="true" />
&nbsp; 6 &nbsp; &nbsp; RAISE expa;<br _extended="true" />
&nbsp; 7 &nbsp; EXCEPTION<br _extended="true" />
&nbsp; 8 &nbsp; &nbsp; WHEN expa THEN<br _extended="true" />
&nbsp; 9 &nbsp; &nbsp; &nbsp; dbms_output.put_line('异常A产生');<br _extended="true" />
10 &nbsp; &nbsp;END;<br _extended="true" />
11 &nbsp;EXCEPTION<br _extended="true" />
12 &nbsp; WHEN expb THEN<br _extended="true" />
13 &nbsp; &nbsp;dbms_output.put_line('异常B产生');<br _extended="true" />
14 &nbsp;END;<br _extended="true" />
15 &nbsp;/<br _extended="true" />
异常A产生<br _extended="true" />
<br _extended="true" />
PL/SQL procedure successfully completed<br _extended="true" />
<br _extended="true" />
SQL&gt;<br _extended="true" />
2)如果当前语句没有该异常的处理程序则通过外层语句块中产生该异常来传播该异常，然后通过外层异常处理程序按步骤１来处理.若外层没有该异常的处理程序则异常传播到调用环境.<br _extended="true" />
<br _extended="true" />
当前语句块没有该异常的处理程序,外层语句块中产生该异常并处理<br _extended="true" />
SQL&gt; DECLARE<br _extended="true" />
&nbsp; 2 &nbsp; expa EXCEPTION;<br _extended="true" />
&nbsp; 3 &nbsp; expb EXCEPTION;<br _extended="true" />
&nbsp; 4 &nbsp;BEGIN<br _extended="true" />
&nbsp; 5 &nbsp; BEGIN<br _extended="true" />
&nbsp; 6 &nbsp; &nbsp; RAISE expb;<br _extended="true" />
&nbsp; 7 &nbsp; EXCEPTION<br _extended="true" />
&nbsp; 8 &nbsp; &nbsp; WHEN expa THEN<br _extended="true" />
&nbsp; 9 &nbsp; &nbsp; &nbsp; dbms_output.put_line('异常A产生');<br _extended="true" />
10 &nbsp; &nbsp;END;<br _extended="true" />
11 &nbsp;EXCEPTION<br _extended="true" />
12 &nbsp; WHEN expb THEN<br _extended="true" />
13 &nbsp; &nbsp;dbms_output.put_line('异常B产生');<br _extended="true" />
14 &nbsp;END;<br _extended="true" />
15 &nbsp;/<br _extended="true" />
异常B产生<br _extended="true" />
<br _extended="true" />
PL/SQL procedure successfully completed<br _extended="true" />
<br _extended="true" />
SQL&gt;<br _extended="true" />
<br _extended="true" />
当前语句块没有该异常的处理程序,外层语句块中产生该异常且没有该异常处理程序，异常传播到调用环境<br _extended="true" />
SQL&gt; DECLARE<br _extended="true" />
&nbsp; 2 &nbsp; expa EXCEPTION;<br _extended="true" />
&nbsp; 3 &nbsp; expb EXCEPTION;<br _extended="true" />
&nbsp; 4 &nbsp;BEGIN<br _extended="true" />
&nbsp; 5 &nbsp; BEGIN<br _extended="true" />
&nbsp; 6 &nbsp; &nbsp; RAISE expb;<br _extended="true" />
&nbsp; 7 &nbsp; EXCEPTION<br _extended="true" />
&nbsp; 8 &nbsp; &nbsp; WHEN expa THEN<br _extended="true" />
&nbsp; 9 &nbsp; &nbsp; &nbsp; dbms_output.put_line('异常A产生');<br _extended="true" />
10 &nbsp; &nbsp;END;<br _extended="true" />
11 &nbsp;EXCEPTION<br _extended="true" />
12 &nbsp; WHEN expa THEN<br _extended="true" />
13 &nbsp; &nbsp;dbms_output.put_line('异常A产生');<br _extended="true" />
14 &nbsp;END;<br _extended="true" />
15 &nbsp;/<br _extended="true" />
<br _extended="true" />
DECLARE<br _extended="true" />
expa EXCEPTION;<br _extended="true" />
expb EXCEPTION;<br _extended="true" />
BEGIN<br _extended="true" />
BEGIN<br _extended="true" />
&nbsp; &nbsp;RAISE expb;<br _extended="true" />
EXCEPTION<br _extended="true" />
&nbsp; &nbsp;WHEN expa THEN<br _extended="true" />
&nbsp; &nbsp; &nbsp;dbms_output.put_line('异常A产生');<br _extended="true" />
&nbsp; END;<br _extended="true" />
EXCEPTION<br _extended="true" />
WHEN expa THEN<br _extended="true" />
&nbsp; dbms_output.put_line('异常A产生');<br _extended="true" />
END;<br _extended="true" />
<br _extended="true" />
ORA-06510: PL/SQL: 无法处理的用户自定义异常事件<br _extended="true" />
ORA-06512: 在line 6<br _extended="true" />
<br _extended="true" />
SQL&gt;<br _extended="true" />
<br _extended="true" />
B声明部分发生的异常<br _extended="true" />
声明部分某赋值发生异常，该异常被立即传播到外层语句块，之后按＂A可执行部分发生的异常＂规则来处理<br _extended="true" />
<br _extended="true" />
SQL&gt; BEGIN<br _extended="true" />
&nbsp; 2 &nbsp; DECLARE<br _extended="true" />
&nbsp; 3 &nbsp; &nbsp; vn NUMBER(1):=25;<br _extended="true" />
&nbsp; 4 &nbsp; BEGIN<br _extended="true" />
&nbsp; 5 &nbsp; &nbsp; NULL;<br _extended="true" />
&nbsp; 6 &nbsp; EXCEPTION<br _extended="true" />
&nbsp; 7 &nbsp; &nbsp; WHEN OTHERS THEN<br _extended="true" />
&nbsp; 8 &nbsp; &nbsp; &nbsp; dbms_output.put_line('异常在内层被处理！');<br _extended="true" />
&nbsp; 9 &nbsp; &nbsp;END;<br _extended="true" />
10 &nbsp;EXCEPTION<br _extended="true" />
11 &nbsp; WHEN OTHERS THEN<br _extended="true" />
12 &nbsp; &nbsp;dbms_output.put_line('异常在外层被处理！');<br _extended="true" />
13 &nbsp;END;<br _extended="true" />
14 &nbsp;/<br _extended="true" />
异常在外层被处理！<br _extended="true" />
<br _extended="true" />
PL/SQL procedure successfully completed<br _extended="true" />
<br _extended="true" />
SQL&gt;<br _extended="true" />
<br _extended="true" />
C异常部分发生的异常<br _extended="true" />
异常处理器中也会产生异常，如RAISE或运行错误产生，这里异常立即被传播到外层同＂B声明部分发生的异常＂<br _extended="true" />
<br _extended="true" />
例子1<br _extended="true" />
SQL&gt;<br _extended="true" />
SQL&gt; BEGIN<br _extended="true" />
&nbsp; 2 &nbsp; DECLARE<br _extended="true" />
&nbsp; 3 &nbsp; &nbsp; expa &nbsp;EXCEPTION;<br _extended="true" />
&nbsp; 4 &nbsp; &nbsp; expb &nbsp;EXCEPTION;<br _extended="true" />
&nbsp; 5 &nbsp; BEGIN<br _extended="true" />
&nbsp; 6 &nbsp; &nbsp; RAISE expa;<br _extended="true" />
&nbsp; 7 &nbsp; EXCEPTION<br _extended="true" />
&nbsp; 8 &nbsp; &nbsp; WHEN expa THEN<br _extended="true" />
&nbsp; 9 &nbsp; &nbsp; &nbsp; RAISE expb;<br _extended="true" />
10 &nbsp; &nbsp; WHEN expb THEN<br _extended="true" />
11 &nbsp;--这里虽然有expb异常处理语句，但是该异常会立即传播到外层<br _extended="true" />
12 &nbsp; &nbsp; &nbsp; dbms_output.put_line('内层捕捉到异常B');<br _extended="true" />
13 &nbsp; &nbsp;END;<br _extended="true" />
14 &nbsp;EXCEPTION<br _extended="true" />
15 &nbsp; WHEN OTHERS THEN<br _extended="true" />
16 &nbsp; &nbsp;dbms_output.put_line('外层捕捉到异常B');<br _extended="true" />
17 &nbsp;END;<br _extended="true" />
18 &nbsp;/<br _extended="true" />
外层捕捉到异常B<br _extended="true" />
<br _extended="true" />
PL/SQL procedure successfully completed<br _extended="true" />
<br _extended="true" />
SQL&gt;<br _extended="true" />
<br _extended="true" />
例子2<br _extended="true" />
SQL&gt; desc t;<br _extended="true" />
Name Type &nbsp; &nbsp; &nbsp;<br _extended="true" />
---- ---------<br _extended="true" />
ID &nbsp; NUMBER(1) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br _extended="true" />
<br _extended="true" />
SQL&gt; BEGIN<br _extended="true" />
&nbsp; 2 &nbsp; DECLARE<br _extended="true" />
&nbsp; 3 &nbsp; &nbsp; expa &nbsp;EXCEPTION;<br _extended="true" />
&nbsp; 4 &nbsp; BEGIN<br _extended="true" />
&nbsp; 5 &nbsp; &nbsp; RAISE expa;<br _extended="true" />
&nbsp; 6 &nbsp; EXCEPTION<br _extended="true" />
&nbsp; 7 &nbsp; &nbsp; WHEN expa THEN<br _extended="true" />
&nbsp; 8 &nbsp; &nbsp; &nbsp; INSERT INTO t VALUES(12);<br _extended="true" />
&nbsp; 9 &nbsp; &nbsp; WHEN OTHERS THEN<br _extended="true" />
10 &nbsp; &nbsp; &nbsp; dbms_output.put_line('内层捕捉到异常');<br _extended="true" />
11 &nbsp; &nbsp;END;<br _extended="true" />
12 &nbsp;EXCEPTION<br _extended="true" />
13 &nbsp; WHEN OTHERS THEN<br _extended="true" />
14 &nbsp; &nbsp;dbms_output.put_line('外层捕捉到异常');<br _extended="true" />
15 &nbsp;END;<br _extended="true" />
16 &nbsp;/<br _extended="true" />
外层捕捉到异常<br _extended="true" />
<br _extended="true" />
PL/SQL procedure successfully completed<br _extended="true" />
SQL&gt;</p>
<p class="content" style="margin: 4px 2px 0px" _extended="true">Oracle内置函数SQLCODE和SQLERRM是特别用在OTHERS处理器中，分别用来返回Oracle的错误代码和错误消息。<br _extended="true" />
OTHERS处理器应该是异常处理块中的最后的异常处理器，因为它是用来捕获除了别的异常处理器处理以外的所有的Oracle异常，所以在程序的最外层使用一个OTHERS处理器的话，将可以确保所有的错误都会被检测到。<br _extended="true" />
<br _extended="true" />
在一个内在的异常中，SQLCODE返回Oracle错误的序号，而SQLERRM返回的是相应的错误消息，错误消息首先显示的是错误代码。SQLCODE返回的是负数，除非Oracle的错误为&#8220;ORA-01403：NO DATA FOUND&#8221;（译：ORA-01403：未找到数据），当Oracle错误为&#8220;ORA-01403：NO DATA FOUND&#8221;时，其对应的SQLCODE为+100。对于用户自定义的异常，SQLCODE返回的是+1，而SQLERRM返回的是User-Defined Exception。<br _extended="true" />
<br _extended="true" />
一个Oracle的错误消息最多只能包含512个字节的错误代码。如果没有异常被触发，则SQLCODE返回0，SQLERRM返回&#8220;ORA-0000：normal, successful completion&#8221;。</p>
<img src ="http://www.blogjava.net/jesenblog/aggbug/188255.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jesenblog/" target="_blank">白露</a> 2008-03-24 15:27 <a href="http://www.blogjava.net/jesenblog/articles/188255.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>java调用oracle数据库里的函数,存储过程和包中的函数,存储过程</title><link>http://www.blogjava.net/jesenblog/articles/188252.html</link><dc:creator>白露</dc:creator><author>白露</author><pubDate>Mon, 24 Mar 2008 07:26:00 GMT</pubDate><guid>http://www.blogjava.net/jesenblog/articles/188252.html</guid><wfw:comment>http://www.blogjava.net/jesenblog/comments/188252.html</wfw:comment><comments>http://www.blogjava.net/jesenblog/articles/188252.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jesenblog/comments/commentRss/188252.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jesenblog/services/trackbacks/188252.html</trackback:ping><description><![CDATA[<div class="middleSize" id="articleContent" _extended="true">
<div _extended="true">
<dl class="body" _extended="true">
<dt class="post-head" _extended="true"><strong _extended="true"><em _extended="true">java调用oracle数据库里的函数,存储过程和包中的函数,存储过程</em></strong><br _extended="true" />
<dd class="post-body last" _extended="true">
<div class="content-wrapper" _extended="true">
<p _extended="true">import java.sql.*;<br _extended="true" />
import oracle.sql.*;</p>
<p _extended="true">public class oracle<br _extended="true" />
{<br _extended="true" />
&nbsp;public static void main(String args[])<br _extended="true" />
&nbsp;{<br _extended="true" />
&nbsp;&nbsp;try<br _extended="true" />
&nbsp;&nbsp;{<br _extended="true" />
&nbsp;&nbsp;&nbsp;DriverManager.registerDriver(new oracle.jdbc.OracleDriver());<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Connection con=DriverManager.getConnection("jdbc:oracle:oci8:@xukai","scott","tiger");<br _extended="true" />
&nbsp;&nbsp;&nbsp;<br _extended="true" />
&nbsp;&nbsp;&nbsp;<br _extended="true" />
&nbsp;&nbsp;&nbsp;<br _extended="true" />
&nbsp;&nbsp;&nbsp;CallableStatement ctst=con.prepareCall("begin&nbsp; ?:=xukaipackage.xukaifun1(?); end;");<br _extended="true" />
&nbsp;&nbsp;&nbsp;ctst.registerOutParameter(1,oracle.jdbc.OracleTypes.CURSOR);<br _extended="true" />
&nbsp;&nbsp;&nbsp;ctst.setInt(2,20);<br _extended="true" />
&nbsp;&nbsp;&nbsp;ctst.execute();<br _extended="true" />
&nbsp;&nbsp;&nbsp;ResultSet rcc=(ResultSet)ctst.getObject(1);<br _extended="true" />
&nbsp;&nbsp;&nbsp;while(rcc.next())<br _extended="true" />
&nbsp;&nbsp;&nbsp;{<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(rcc.getString(1)+","+rcc.getString(2)+","+rcc.getString(3)+","+rcc.getString(4)+","+rcc.getString(5)+","+rcc.getString(6)+","+rcc.getString(7)+","+rcc.getString(8));<br _extended="true" />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;}<br _extended="true" />
&nbsp;&nbsp;&nbsp;<br _extended="true" />
&nbsp;&nbsp;}<br _extended="true" />
&nbsp;&nbsp;catch(Exception e)<br _extended="true" />
&nbsp;&nbsp;{<br _extended="true" />
&nbsp;&nbsp;&nbsp;e.printStackTrace();<br _extended="true" />
&nbsp;&nbsp;}<br _extended="true" />
&nbsp;}<br _extended="true" />
}</p>
</div>
</dd></dl></div>
<div class="invisible" id="reference" _extended="true">文章引用自：<a href=" _extended=" target="true"  ?></a> </div>
</div>
<img src ="http://www.blogjava.net/jesenblog/aggbug/188252.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jesenblog/" target="_blank">白露</a> 2008-03-24 15:26 <a href="http://www.blogjava.net/jesenblog/articles/188252.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>oracle 常用数据字典 </title><link>http://www.blogjava.net/jesenblog/articles/188250.html</link><dc:creator>白露</dc:creator><author>白露</author><pubDate>Mon, 24 Mar 2008 07:25:00 GMT</pubDate><guid>http://www.blogjava.net/jesenblog/articles/188250.html</guid><wfw:comment>http://www.blogjava.net/jesenblog/comments/188250.html</wfw:comment><comments>http://www.blogjava.net/jesenblog/articles/188250.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jesenblog/comments/commentRss/188250.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jesenblog/services/trackbacks/188250.html</trackback:ping><description><![CDATA[一、用户<br _extended="true" />
<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 查看当前用户的缺省表空间<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SQL&gt;select username,default_tablespace from user_users;<br _extended="true" />
<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 查看当前用户的角色<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SQL&gt;select * from user_role_privs;<br _extended="true" />
<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 查看当前用户的系统权限和表级权限<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SQL&gt;select * from user_sys_privs;<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SQL&gt;select * from user_tab_privs;<br _extended="true" />
<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 二、表<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 查看用户下所有的表<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SQL&gt;select * from user_tables;<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 查看名称包含log字符的表<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SQL&gt;select object_name,object_id from user_objects where instr(object_name,'LOG')&gt;0;<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 查看某表的创建时间<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SQL&gt;select object_name,created from user_objects where object_name=upper('&amp;table_name');<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 查看某表的大小<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SQL&gt;select sum(bytes)/(1024*1024) as size(M) from user_segments where segment_name=upper('&amp;table_name');<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 查看放在ORACLE的内存区里的表&nbsp;&nbsp;<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SQL&gt;select table_name,cache from user_tables where instr(cache,'Y')&gt;0;<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 三、索引<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 查看索引个数和类别<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SQL&gt;select index_name,index_type,table_name from user_indexes order by table_name;
<div _extended="true">查看索引被索引的字段<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SQL&gt;select * from user_ind_columns where index_name=upper('&amp;index_name');<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 查看索引的大小<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SQL&gt;select sum(bytes)/(1024*1024) as size(M) from user_segments where segment_name=upper('&amp;index_name');<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 四、序列号<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 查看序列号，last_number是当前值<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SQL&gt;select * from user_sequences;<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 五、视图<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 查看视图的名称<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SQL&gt;select view_name from user_views;<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 查看创建视图的select语句<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SQL&gt;select view_name,text_length from user_views;<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SQL&gt;set long 2000;说明：可以根据视图的text_length值设定set long 的大小<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SQL&gt;select text from user_views where view_name=upper('&amp;view_name');<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 六、同义词<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 查看同义词的名称<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SQL&gt;select * from user_synonyms;<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 七、约束条件<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 查看某表的约束条件<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SQL&gt;select constraint_name, constraint_type,search_condition, r_constraint_name from user_constraints where table_name = upper('&amp;table_name');<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SQL&gt;select c.constraint_name,c.constraint_type,cc.column_name&nbsp;&nbsp;<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; from user_constraints c,user_cons_columns cc<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; where c.owner = upper('&amp;table_owner') and c.table_name = upper('&amp;table_name')<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; and c.owner = cc.owner and c.constraint_name = cc.constraint_name<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; order by cc.position;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 八、存储函数和过程<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 查看函数和过程的状态<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SQL&gt;select object_name,status from user_objects where object_type='FUNCTION';<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SQL&gt;select object_name,status from user_objects where object_type='PROCEDURE';<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 查看函数和过程的源代码<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SQL&gt;select text from all_source where owner=user and name=upper('&amp;plsql_name');<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 九、触发器<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 查看触发器<br _extended="true" />
<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; set long 50000;<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; set heading off;<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; set pagesize 2000;<br _extended="true" />
<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; select<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 'create or replace trigger ' ||<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; trigger_name || '' || chr(10)||<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; decode( substr( trigger_type, 1, 1 ),<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 'A', 'AFTER', 'B', 'BEFORE', 'I', 'INSTEAD OF' ) ||<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; chr(10) ||<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; triggering_event || chr(10) ||<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 'ON ' || table_owner || '.' ||<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; table_name || '' || chr(10) ||<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; decode( instr( trigger_type, 'EACH ROW' ), 0, null,<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 'FOR EACH ROW' ) || chr(10) ,<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; trigger_body<br _extended="true" />
</div>
<div class="invisible" id="reference" _extended="true">文章引用自：<a href=" _extended=" target="true"  ?></a> </div>
<img src ="http://www.blogjava.net/jesenblog/aggbug/188250.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jesenblog/" target="_blank">白露</a> 2008-03-24 15:25 <a href="http://www.blogjava.net/jesenblog/articles/188250.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>oracle嵌套事务</title><link>http://www.blogjava.net/jesenblog/articles/188249.html</link><dc:creator>白露</dc:creator><author>白露</author><pubDate>Mon, 24 Mar 2008 07:24:00 GMT</pubDate><guid>http://www.blogjava.net/jesenblog/articles/188249.html</guid><wfw:comment>http://www.blogjava.net/jesenblog/comments/188249.html</wfw:comment><comments>http://www.blogjava.net/jesenblog/articles/188249.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jesenblog/comments/commentRss/188249.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jesenblog/services/trackbacks/188249.html</trackback:ping><description><![CDATA[<p _extended="true"><font face="宋体" _extended="true">AUTONOMOUS TRANSACTION(自治事务)的介绍</font></p>
<p _extended="true">&nbsp;</p>
<p _extended="true"><font face="宋体" _extended="true">在基于低版本的ORACLE做一些项目的过程中,有时会遇到一些头疼的问题.,比如想在执行当前一个由多个DML组成的transaction(事务)时,为每一步DML记录一些信息到跟踪表中,由于事务的原子性,这些跟踪信息的提交将决定于主事务的commit或rollback. 这样一来写程序的难度就增大了, 程序员不得不把这些跟踪信息记录到类似数组的结构中,然后在主事务结束后把它们存入跟踪表.哎,真是麻烦!</font></p>
<p _extended="true"><font face="宋体" _extended="true">有没有一个简单的方法解决类似问题呢？</font></p>
<p _extended="true"><font face="宋体" _extended="true">ORACLE8i的AUTONOMOUS TRANSACTION(自治事务，以下AT)是一个很好的回答。</font></p>
<p _extended="true"><font face="宋体" _extended="true">AT 是由主事务(以下MT)调用但是独立于它的事务。在AT被调用执行时，MT被挂起，在AT内部，一系列的DML可以被执行并且commit或rollback.</font></p>
<p _extended="true"><font face="宋体" _extended="true">注意由于AT的独立性，它的commit和rollback并不影响MT的执行效果。在AT执行结束后，主事务获得控制权，又可以继续执行了。</font></p>
<font face="宋体" _extended="true">&nbsp;</font>
<p _extended="true"><font face="宋体" _extended="true">如何实现AT的定义呢？我们来看一下它的语法。其实非常简单。</font></p>
<p _extended="true"><font face="宋体" _extended="true">只需下列PL/SQL的声明部分加上<strong _extended="true"><u _extended="true">PRAGMA</u></strong> <font size="2" _extended="true"><code _extended="true"><strong _extended="true"><u _extended="true">AUTONOMOUS_TRANSACTION</u></strong></code> 就可以了。</font></font></p>
<p _extended="true"><font face="宋体" _extended="true">1．<font size="2" _extended="true">&nbsp;</font> 顶级的匿名PL/SQL块</font></p>
<p _extended="true"><font face="宋体" _extended="true">2．<font size="2" _extended="true">&nbsp;</font> Functions 或 Procedure（独立声明或声明在package中都可）</font></p>
<p _extended="true"><font face="宋体" _extended="true">3．<font size="2" _extended="true">&nbsp;</font> SQL Object Type的方法</font></p>
<p _extended="true"><font face="宋体" _extended="true">4．<font size="2" _extended="true">&nbsp;</font> 触发器。</font></p>
<p _extended="true"><font face="宋体" _extended="true">&nbsp;</font></p>
<p _extended="true"><font face="宋体" _extended="true">&nbsp;&nbsp;&nbsp;&nbsp;</font></p>
<p _extended="true"><font face="宋体" _extended="true">&nbsp;</font></p>
<p _extended="true"><font face="宋体" _extended="true">&nbsp;</font></p>
<p _extended="true"><font face="宋体" _extended="true">比如：</font></p>
<p _extended="true"><font face="宋体" _extended="true">&nbsp;</font></p>
<p _extended="true"><font face="宋体" _extended="true">在一个独立的procedure中声明AT</font></p>
<p _extended="true"><font face="宋体" _extended="true">CREATE OR REPLACE PROCEDURE</font></p>
<p _extended="true"><font face="宋体" _extended="true">&nbsp;&nbsp; Log_error(error_msg IN VARCHAR2(100))</font></p>
<p _extended="true"><font face="宋体" _extended="true">IS</font></p>
<p _extended="true"><font face="宋体" _extended="true">&nbsp; <strong _extended="true">&nbsp;<u _extended="true">PRAGMA AUTONOMOUS_TRANSACTION;</u></strong></font></p>
<p _extended="true"><font face="宋体" _extended="true">BEGIN</font></p>
<p _extended="true"><font face="宋体" _extended="true">&nbsp;&nbsp; Insert into Error_log values ( sysdate,error_msg);</font></p>
<p _extended="true"><font face="宋体" _extended="true">&nbsp;&nbsp; COMMIT;</font></p>
<p _extended="true"><font face="宋体" _extended="true">END;</font></p>
<p _extended="true"><font face="宋体" _extended="true">&nbsp;</font></p>
<p _extended="true"><font face="宋体" _extended="true">下面我们来看一个例子，（win2000 advanced server + oracle8.1.6 , connect as scott）</font></p>
<p _extended="true"><font face="宋体" _extended="true">建立一个表:</font></p>
<p _extended="true"><font face="宋体" _extended="true">create table msg (msg varchar2(120));</font></p>
<p _extended="true"><font face="宋体" _extended="true">首先,用普通的事务写个匿名PL/SQL块：</font></p>
<p _extended="true"><font face="宋体" _extended="true">&nbsp;</font></p>
<p _extended="true"><font face="宋体" _extended="true">declare</font></p>
<p _extended="true"><font face="宋体" _extended="true">&nbsp;&nbsp; cnt&nbsp; number := -1;&nbsp;&nbsp; --} Global variables</font></p>
<p _extended="true"><font face="宋体" _extended="true">&nbsp;&nbsp; procedure local is</font></p>
<p _extended="true"><font face="宋体" _extended="true">&nbsp;&nbsp; begin</font></p>
<p _extended="true"><font face="宋体" _extended="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; select count(*) into cnt from msg;</font></p>
<p _extended="true"><font face="宋体" _extended="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dbms_output.put_line('local: # of rows is '||cnt);</font></p>
<p _extended="true"><font face="宋体" _extended="true">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;</font></p>
<p _extended="true"><font face="宋体" _extended="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; insert into msg values ('New Record');</font></p>
<p _extended="true"><font face="宋体" _extended="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; commit;</font></p>
<p _extended="true"><font face="宋体" _extended="true">&nbsp;&nbsp; end;</font></p>
<p _extended="true"><font face="宋体" _extended="true">&nbsp;</font></p>
<p _extended="true"><font face="宋体" _extended="true">&nbsp;</font></p>
<p _extended="true"><font face="宋体" _extended="true">&nbsp;</font></p>
<p _extended="true"><font face="宋体" _extended="true">&nbsp;</font></p>
<p _extended="true"><font face="宋体" _extended="true">&nbsp;</font></p>
<p _extended="true"><font face="宋体" _extended="true">&nbsp;&nbsp; begin</font></p>
<p _extended="true"><font face="宋体" _extended="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; delete from msg ;</font></p>
<p _extended="true"><font face="宋体" _extended="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; commit;</font></p>
<p _extended="true"><font face="宋体" _extended="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; insert into msg values ('Row 1');</font></p>
<p _extended="true"><font face="宋体" _extended="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; local;</font></p>
<p _extended="true"><font face="宋体" _extended="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; select count(*) into cnt from msg;</font></p>
<p _extended="true"><font face="宋体" _extended="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dbms_output.put_line('main: # of rows is '||cnt);</font></p>
<p _extended="true"><font face="宋体" _extended="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rollback;</font></p>
<p _extended="true"><font face="宋体" _extended="true">&nbsp;</font></p>
<p _extended="true"><font face="宋体" _extended="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; local;</font></p>
<p _extended="true"><font face="宋体" _extended="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; insert into msg values ('Row 2');</font></p>
<p _extended="true"><font face="宋体" _extended="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; commit;</font></p>
<p _extended="true"><font face="宋体" _extended="true">&nbsp;</font></p>
<p _extended="true"><font face="宋体" _extended="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; local;</font></p>
<p _extended="true"><font face="宋体" _extended="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; select count(*) into cnt from msg;</font></p>
<p _extended="true"><font face="宋体" _extended="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dbms_output.put_line('main: # of rows is '||cnt);</font></p>
<p _extended="true"><font face="宋体" _extended="true">&nbsp;&nbsp; end;</font></p>
<p _extended="true"><font face="宋体" _extended="true">&nbsp;</font></p>
<p _extended="true"><font face="宋体" _extended="true">运行结果(注意打开serveroutput)</font></p>
<p _extended="true"><font face="宋体" _extended="true">&nbsp;</font></p>
<p _extended="true"><font face="宋体" _extended="true">local: # of rows is 1&nbsp;&nbsp; -&gt; 子程序local中可以&#8217;看到&#8217;主匿名块中的uncommitted记录</font></p>
<p _extended="true"><font face="宋体" _extended="true">main: # of rows is 2&nbsp;&nbsp;&nbsp; -&gt; 主匿名块可以&#8217;看到&#8217;2条记录(它们都是被local commit掉的)</font></p>
<p _extended="true"><font face="宋体" _extended="true">local: # of rows is 2&nbsp;&nbsp; -&gt; 子程序local首先&#8217;看到&#8217;2条记录,然后又commit了第三条记录</font></p>
<p _extended="true"><font face="宋体" _extended="true">local: # of rows is 4&nbsp;&nbsp; -&gt; 子程序local又&#8217;看到&#8217;了新增加的记录(它们都是被local commit掉的),然后又commit了第五条记录</font></p>
<p _extended="true"><font face="宋体" _extended="true">main: # of rows is 5&nbsp;&nbsp;&nbsp; -&gt; 主匿名块最后&#8217;看到&#8217;了所有的记录.</font></p>
<p _extended="true"><font face="宋体" _extended="true">&nbsp;</font></p>
<p _extended="true"><font face="宋体" _extended="true">&nbsp;</font></p>
<p _extended="true"><font face="宋体" _extended="true">从这个例子中,我们看到COMMIT和ROLLBACK的位置无论是在主匿名块中或者在子程序中,都会影响到整个当前事务.</font></p>
<p _extended="true"><font face="宋体" _extended="true">&nbsp;</font></p>
<p _extended="true"><font face="宋体" _extended="true">&nbsp;</font></p>
<p _extended="true"><font face="宋体" _extended="true">&nbsp;</font></p>
<p _extended="true"><font face="宋体" _extended="true">&nbsp;</font></p>
<p _extended="true"><font face="宋体" _extended="true">&nbsp;</font></p>
<p _extended="true"><font face="宋体" _extended="true">现在用AT改写一下匿名块中的procedure local:</font></p>
<p _extended="true"><font face="宋体" _extended="true">...</font></p>
<p _extended="true"><font face="宋体" _extended="true">&nbsp;&nbsp; procedure local is</font></p>
<p _extended="true"><font face="宋体" _extended="true">&nbsp;&nbsp;&nbsp;&nbsp; <strong _extended="true"><u _extended="true">&nbsp;pragma AUTONOMOUS_TRANSACTION;</u></strong></font></p>
<p _extended="true"><font face="宋体" _extended="true">&nbsp;&nbsp; begin</font></p>
<p _extended="true"><font face="宋体" _extended="true">...</font></p>
<p _extended="true"><font face="宋体" _extended="true">&nbsp;</font></p>
<p _extended="true"><font face="宋体" _extended="true">重新运行(注意打开serveroutput)</font></p>
<p _extended="true"><font face="宋体" _extended="true">local: # of rows is 0&nbsp;&nbsp; -&gt; <strong _extended="true">子程序local中无法可以&#8217;看到&#8217;主匿名块中的uncommitted记录 (因为它是独立的)</strong></font></p>
<p _extended="true"><font face="宋体" _extended="true">main: # of rows is 2&nbsp;&nbsp;&nbsp; -&gt; <strong _extended="true">主匿名块可以&#8217;看到&#8217;2条记录,但只有一条是被commited.</strong></font></p>
<p _extended="true"><font face="宋体" _extended="true">local: # of rows is 1&nbsp;&nbsp; -&gt; <strong _extended="true">子程序local中可以&#8217;看到&#8217;它前一次commit的记录,但是主匿名块中的记录已经被提前rollback了</strong></font></p>
<p _extended="true"><font face="宋体" _extended="true">local: # of rows is 3&nbsp;&nbsp; -&gt; 子程序local 中可以&#8217;看到&#8217;3条记录包括主匿名块commit的记录</font></p>
<p _extended="true"><font face="宋体" _extended="true">main: # of rows is 4&nbsp;&nbsp;&nbsp; -&gt;主匿名块最后&#8217;看到&#8217;了所有的记录.</font></p>
<p _extended="true"><font face="宋体" _extended="true">&nbsp;</font></p>
<p _extended="true"><font face="宋体" _extended="true">很明显,AT是独立的,在它执行时,MT被暂停了. AT的COMMIT,ROLLBACK并不影响MT的执行.</font></p>
<p _extended="true"><font face="宋体" _extended="true">&nbsp;</font></p>
<p _extended="true"><font face="宋体" _extended="true">运用AT时,有一些注意事项,简单列举如下:</font></p>
<p _extended="true"><font face="宋体" _extended="true">1.<font size="2" _extended="true">&nbsp;&nbsp;&nbsp;&nbsp;</font> 在匿名PL/SQL块中,只有顶级的匿名PL/SQL块可以被设为AT</font></p>
<p _extended="true"><font face="宋体" _extended="true">2.<font size="2" _extended="true">&nbsp;&nbsp;&nbsp;&nbsp;</font> 如果AT试图访问被MT控制的资源,可能有deadlock发生.</font></p>
<p _extended="true"><font face="宋体" _extended="true">3.<font size="2" _extended="true">&nbsp;&nbsp;&nbsp;&nbsp;</font> Package 不能被声明为AT,只有package所拥有的function和procedure 才能声明为AT</font></p>
<p _extended="true"><font face="宋体" _extended="true">4.<font size="2" _extended="true">&nbsp;&nbsp;&nbsp;&nbsp;</font> AT程序必须以commit 或rollback结尾,否则会产生Oracle错误ORA-06519: active autonomous transaction detected and rolled back</font></p>
<p _extended="true"><font face="宋体" _extended="true">&nbsp;</font></p>
<p _extended="true"><font face="宋体" _extended="true">在程序开发时,如果充分运用AUTONOMOUS TRANSACTION的特性,一定能取得事倍功半的效果.<br />
<br />
<br />
</font><strong style="color: #993300">可以使用自住事务解决触发器变异表的问题.(变异表mutating table:是指执行触发器时正在被修改的表&lt;upadate或delete触发器&gt;,由于更新而激发的表,不准许查询或修改正在修改的表.</strong></p>
<img src ="http://www.blogjava.net/jesenblog/aggbug/188249.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jesenblog/" target="_blank">白露</a> 2008-03-24 15:24 <a href="http://www.blogjava.net/jesenblog/articles/188249.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>oracle批绑定 </title><link>http://www.blogjava.net/jesenblog/articles/188245.html</link><dc:creator>白露</dc:creator><author>白露</author><pubDate>Mon, 24 Mar 2008 07:13:00 GMT</pubDate><guid>http://www.blogjava.net/jesenblog/articles/188245.html</guid><wfw:comment>http://www.blogjava.net/jesenblog/comments/188245.html</wfw:comment><comments>http://www.blogjava.net/jesenblog/articles/188245.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jesenblog/comments/commentRss/188245.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jesenblog/services/trackbacks/188245.html</trackback:ping><description><![CDATA[<div _extended="true">采用bulk collect可以将查询结果一次性地加载到collections中。而不是通过cursor一条一条地处理。可以在select into,fetch into,returning into语句使用bulk collect。注意在使用bulk collect时，所有的into变量都必须是collections.</div>
<div _extended="true">&nbsp;<br _extended="true" />
举几个简单的例子：</div>
<div _extended="true"><font color="#339966" _extended="true"><strong _extended="true">--在select into语句中使用bulk collect</strong></font></div>
<div _extended="true">DECLARE<br _extended="true" />
TYPE SalList IS TABLE OF emp.sal%TYPE;<br _extended="true" />
sals SalList;<br _extended="true" />
BEGIN<br _extended="true" />
-- Limit the number of rows to 100.<br _extended="true" />
SELECT sal BULK COLLECT INTO sals FROM emp<br _extended="true" />
WHERE ROWNUM &lt;= 100;<br _extended="true" />
-- Retrieve 10% (approximately) of the rows in the table.<br _extended="true" />
SELECT sal BULK COLLECT INTO sals FROM emp SAMPLE 10;</div>
<div _extended="true">END;<br _extended="true" />
/</div>
<div _extended="true"><strong _extended="true"><font color="#339966" _extended="true">--在fetch into中使用bulk collect</font></strong></div>
<div _extended="true">DECLARE<br _extended="true" />
TYPE DeptRecTab IS TABLE OF dept%ROWTYPE;<br _extended="true" />
dept_recs DeptRecTab;<br _extended="true" />
CURSOR c1 IS<br _extended="true" />
SELECT deptno, dname, loc FROM dept WHERE deptno &gt; 10;<br _extended="true" />
BEGIN<br _extended="true" />
OPEN c1;<br _extended="true" />
FETCH c1 BULK COLLECT INTO dept_recs;<br _extended="true" />
END;<br _extended="true" />
/</div>
<div _extended="true"><strong _extended="true"><font color="#339966" _extended="true">--在returning into中使用bulk collect</font></strong></div>
<div _extended="true">CREATE TABLE emp2 AS SELECT * FROM employees;<br _extended="true" />
DECLARE<br _extended="true" />
TYPE NumList IS TABLE OF employees.employee_id%TYPE;<br _extended="true" />
enums NumList;<br _extended="true" />
TYPE NameList IS TABLE OF employees.last_name%TYPE;<br _extended="true" />
names NameList;<br _extended="true" />
BEGIN<br _extended="true" />
DELETE FROM emp2 WHERE department_id = 30<br _extended="true" />
RETURNING employee_id, last_name BULK COLLECT INTO enums, names;<br _extended="true" />
dbms_output.put_line('Deleted ' || SQL%ROWCOUNT || ' rows:');<br _extended="true" />
FOR i IN enums.FIRST .. enums.LAST<br _extended="true" />
LOOP<br _extended="true" />
dbms_output.put_line('Employee #' || enums(i) || ': ' || names(i));<br _extended="true" />
END LOOP;<br _extended="true" />
END;<br _extended="true" />
/<br _extended="true" />
DROP TABLE emp2;</div>
<div _extended="true">&nbsp;</div>
<div _extended="true">&nbsp;</div>
<h3 _extended="true">oracle批量绑定forall bulk collect</h3>
<div _extended="true">oracle批量绑定forall bulk collect <a href="http://otn.oracle.com/oramag/oracle...tech_plsql.html" target="_blank" _extended="true">http://otn.oracle.com/oramag/oracle...tech_plsql.html</a></div>
<div _extended="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <a href="http://otn.oracle.com/docs/products...colls.htm#23723" target="_blank" _extended="true">http://otn.oracle.com/docs/products...colls.htm#23723</a></div>
<div _extended="true"><span class="javascript" id="text793504" style="font-size: 12px" _extended="true">关于Bulk Binds中LIMIT的使用，请看TOM的解说<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <a href="http://asktom.oracle.com/pls/ask/f?...5918938803188,Y" target="_blank" _extended="true">http://asktom.oracle.com/pls/ask/f?...5918938803188,Y</a></span></div>
<div _extended="true"><span class="javascript" style="font-size: 12px" _extended="true"><span class="javascript" style="font-size: 12px" _extended="true"><span class="javascript" id="text1134136" style="font-size: 12px" _extended="true">Oracle10g中对于forall的增强<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <a href="http://www.itpub.net/showthread.php?s=&amp;threadid=184794" target="_blank" _extended="true">http://www.itpub.net/showthread.php?s=&amp;threadid=184794</a></span></span></span></div>
<div _extended="true">批量绑定（Bulk binds）可以通过减少在PL/SQL和SQL引擎之间的上下文切换(context switches )提高了性能.</div>
<div _extended="true"><br _extended="true" />
批量绑定（Bulk binds）包括：<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(i) Input collections, use the FORALL statement，用来改善DML（INSERT、UPDATE和DELETE) 操作的性能<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;(ii) Output collections, use BULK COLLECT clause，一般用来提高查询（SELECT）的性能</div>
<div _extended="true"><br _extended="true" />
10g开始forall语句可以使用三种方式：<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; i in low..up<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; i in indices of collection&nbsp; 取得集合元素下标的值<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; i in values of collection&nbsp;&nbsp; 取得集合元素的值<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; forall语句还可以使用部分集合元素</div>
<div _extended="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sql%bulk_rowcount(i)表示forall语句第i元素所作用的行数</div>
<div _extended="true">CREATE TABLE parts1 (pnum INTEGER, pname VARCHAR2(15));<br _extended="true" />
CREATE TABLE parts2 (pnum INTEGER, pname VARCHAR2(15));<br _extended="true" />
CREATE TABLE parts3 (pnum INTEGER, pname VARCHAR2(15));<br _extended="true" />
CREATE TABLE parts4 (pnum INTEGER, pname VARCHAR2(15));</div>
<div _extended="true">set &nbsp; serveroutput &nbsp; on&nbsp;&nbsp; --把屏幕显示开关置上<br _extended="true" />
</div>
<div _extended="true">DECLARE<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp; TYPE NumTab IS TABLE OF parts1.pnum%TYPE INDEX BY PLS_INTEGER;<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp; TYPE NameTab IS TABLE OF parts1.pname%TYPE INDEX BY PLS_INTEGER;<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp; pnums NumTab;<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pnames NameTab;<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp; iterations CONSTANT PLS_INTEGER := 50000;<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp; t1 INTEGER; t2 INTEGER; t3 INTEGER; t4 INTEGER; t5 INTEGER;<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp; stmt_str varchar2(255);table_name varchar2(255);<br _extended="true" />
BEGIN<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp; FOR j IN 1..iterations LOOP -- load index-by tables<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pnums(j) := j;<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pnames(j) := 'Part No. ' || TO_CHAR(j);<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp; END LOOP;<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;</div>
<div _extended="true">&nbsp;&nbsp;&nbsp;&nbsp; t1 := dbms_utility.get_time;<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp; FOR i IN 1..iterations LOOP -- use FOR loop<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; INSERT INTO parts1 VALUES (pnums(i), pnames(i));<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp; END LOOP;<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;</div>
<div _extended="true">&nbsp;&nbsp;&nbsp;&nbsp; t2 := dbms_utility.get_time;<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp; FORALL i IN 1..iterations -- use FORALL statement<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; INSERT INTO parts2 VALUES (pnums(i), pnames(i));<br _extended="true" />
<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp; t3 := dbms_utility.get_time;<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp; table_name:='parts3';<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp; stmt_str := 'INSERT INTO ' || table_name || ' values (:num, :pname)';<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp; FOR i IN 1..iterations LOOP -- use FORALL statement<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; EXECUTE IMMEDIATE stmt_str USING pnums(i), pnames(i);<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp; END LOOP;<br _extended="true" />
<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp; t4 := dbms_utility.get_time;<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp; table_name:='parts4';<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp; stmt_str := 'INSERT INTO ' || table_name || ' values (:num, :pname)';<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp; FORALL i IN 1..iterations-- use FORALL statement<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; EXECUTE IMMEDIATE stmt_str USING pnums(i), pnames(i);<br _extended="true" />
</div>
<div _extended="true">&nbsp;&nbsp;&nbsp;&nbsp; t5 := dbms_utility.get_time;<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp; dbms_output.put_line('Execution Time (secs)');<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp; dbms_output.put_line('---------------------');<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp; dbms_output.put_line('FOR loop: ' || TO_CHAR((t2 - t1)/100));<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp; dbms_output.put_line('FORALL: ' || TO_CHAR((t3 - t2)/100));<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp; dbms_output.put_line('FOR loop: ' || TO_CHAR((t4 - t3)/100));<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp; dbms_output.put_line('FORALL: ' || TO_CHAR((t5 - t4)/100));<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;</div>
<div _extended="true">&nbsp;&nbsp;&nbsp;&nbsp; COMMIT;<br _extended="true" />
END;<br _extended="true" />
/</div>
<div _extended="true"><br _extended="true" />
DROP TABLE parts1;<br _extended="true" />
DROP TABLE parts2;<br _extended="true" />
DROP TABLE parts3;</div>
<div _extended="true">DROP TABLE parts4;</div>
<div _extended="true">
<h3 _extended="true">使用Bulk Collect提高Oracle查询效率</h3>
<p _extended="true">Oracle8i中首次引入了Bulk Collect特性，该特性可以让我们在PL/SQL中能使用批查询，批查询在某些情况下能显著提高查询效率。现在，我们对该特性进行一些简单的测试和分析。<br _extended="true" />
<br _extended="true" />
<strong _extended="true">1．&nbsp;首先，我们创建一个表，并插入100000条记录<br _extended="true" />
</strong>在SQL/Plus中执行下列脚本：<br _extended="true" />
<br _extended="true" />
drop table empl_tbl<br _extended="true" />
/<br _extended="true" />
create table empl_tbl(last_name varchar2(20),<br _extended="true" />
first_name varchar2(10),<br _extended="true" />
salary number(10))<br _extended="true" />
/</p>
<p _extended="true">begin<br _extended="true" />
for i in 3000..102999 loop<br _extended="true" />
insert into empl_tbl(last_name,first_name,salary) values('carl'||(i-3000),'wu'||(103000-i),i);<br _extended="true" />
end loop;<br _extended="true" />
end;<br _extended="true" />
/<br _extended="true" />
commit<br _extended="true" />
/<br _extended="true" />
select count(*) from empl_tbl;<br _extended="true" />
/</p>
<p _extended="true"><strong _extended="true">2．&nbsp;使用三种方法计算表中某一字段含有多少个不重复值</strong></p>
<p _extended="true">2.1 使用常规的Distinct来实现</p>
<p _extended="true">SQL&gt; select count(distinct last_name) "Distinct Last Name" from empl_tbl;</p>
<p _extended="true">Distinct Last Name<br _extended="true" />
------------------<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 100000<br _extended="true" />
&nbsp;<br _extended="true" />
Executed in 0.36 seconds</p>
<p _extended="true">我们可以看到，常规方法需要0.36秒查出该表中有100000个不重复的Last_name值。</p>
<p _extended="true">2.2 使用游标来实现</p>
<p _extended="true">我们执行下面语句来统计Last_name字段的不重复值个数：</p>
<p _extended="true">declare<br _extended="true" />
&nbsp; all_rows number(10);<br _extended="true" />
&nbsp; temp_last_name empl_tbl.last_name%type;<br _extended="true" />
begin<br _extended="true" />
&nbsp; all_rows:=0;<br _extended="true" />
&nbsp; temp_last_name:=' ';<br _extended="true" />
&nbsp; <strong _extended="true">for cur in (select last_name from empl_tbl order by last_name) loop</strong><br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if cur.last_name!=temp_last_name then<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; all_rows:=all_rows+1;<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; end if;<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; temp_last_name:=cur.last_name;<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br _extended="true" />
&nbsp; end loop;<br _extended="true" />
&nbsp; dbms_output.put_line('all_rows are '||all_rows);<br _extended="true" />
end;</p>
<p _extended="true">请注意上面代码中的黑体部分使用了一个For Loop游标，为了提高程序可读性，我们没有显示定义游标变量。</p>
<p _extended="true">执行结果：<br _extended="true" />
all_rows are 100000<br _extended="true" />
PL/SQL procedure successfully completed<br _extended="true" />
Executed in 1.402 seconds</p>
<p _extended="true">游标需要1.4秒才能查出该表中有100000个不重复的Last_name值，所耗时间是Distinct查询的3倍多。</p>
<p _extended="true">2.3 使用Bulk Collect批查询来实现</p>
<p _extended="true">示例代码如下：<br _extended="true" />
declare<br _extended="true" />
&nbsp; all_rows number(10);<br _extended="true" />
&nbsp; --首先，定义一个Index-by表数据类型<br _extended="true" />
&nbsp; type last_name_tab is table of empl_tbl.last_name%type index by binary_integer;<br _extended="true" />
&nbsp; last_name_arr last_name_tab;<br _extended="true" />
&nbsp; --定义一个Index-by表集合变量<br _extended="true" />
&nbsp; temp_last_name empl_tbl.last_name%type;<br _extended="true" />
&nbsp;<br _extended="true" />
begin<br _extended="true" />
&nbsp; all_rows:=0;<br _extended="true" />
&nbsp; temp_last_name:=' ';<br _extended="true" />
&nbsp; --使用Bulk Collect批查询来充填集合变量<br _extended="true" />
&nbsp; select last_name bulk collect into last_name_arr from empl_tbl;<br _extended="true" />
&nbsp;<br _extended="true" />
&nbsp; for i in 1..last_name_arr.count loop<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if temp_last_name!=last_name_arr(i) then<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; all_rows:=all_rows+1;<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; end if;<br _extended="true" />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; temp_last_name:=last_name_arr(i);<br _extended="true" />
&nbsp; end loop;<br _extended="true" />
&nbsp;dbms_output.put_line('all_rows are '||all_rows);<br _extended="true" />
end;</p>
<p _extended="true">请注意上面代码中，我们首先定义了一个Index-by表数据类型last_name_tab，然后定义了一个该集合数据类型的变量last_name_arr，最后我们使用Bulk Collect批查询来充填last_name_arr，请注意它的使用语法。</p>
<p _extended="true">执行结果：<br _extended="true" />
all_rows are 100000<br _extended="true" />
PL/SQL procedure successfully completed<br _extended="true" />
Executed in 0.28 seconds<br _extended="true" />
从上面执行结果，我们可以看到，Bulk Collect批查询只需要0.28秒就能查出该表中有100000个不重复的Last_name值，所耗时间只有游标查询的1/5，同时它比Distinct常规查询的速度也要快。</p>
</div>
<img src ="http://www.blogjava.net/jesenblog/aggbug/188245.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jesenblog/" target="_blank">白露</a> 2008-03-24 15:13 <a href="http://www.blogjava.net/jesenblog/articles/188245.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>oracle权限概述 </title><link>http://www.blogjava.net/jesenblog/articles/188243.html</link><dc:creator>白露</dc:creator><author>白露</author><pubDate>Mon, 24 Mar 2008 07:10:00 GMT</pubDate><guid>http://www.blogjava.net/jesenblog/articles/188243.html</guid><wfw:comment>http://www.blogjava.net/jesenblog/comments/188243.html</wfw:comment><comments>http://www.blogjava.net/jesenblog/articles/188243.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jesenblog/comments/commentRss/188243.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jesenblog/services/trackbacks/188243.html</trackback:ping><description><![CDATA[<p _extended="true"><font face="宋体" _extended="true">一、权限概述<br _extended="true" />
　　权限是用户对一项功能的执行权力。在Oracle中，根据系统管理方式不同，将权限分为系统权限与实体权限两类。系统权限是指是否被授权用户可以连接到数据库上，在数据库中可以进行哪些系统操作。而实体权限是指用户对具体的模式实体(schema)所拥有的权限。这样讲可以有些模糊，举个例子来说：select any table是系统权限，它表示可以查看任何表。而select on table1是实体权限，表示对表table1的查询权限。</font></p>
<p _extended="true"><font face="宋体" _extended="true">二、系统权限列表<br _extended="true" />
　　在这里我们列出所有的权限，并将它们分类。这里只列出权限名，有关权限的详细说明请参考oracle官方参考手册。<br _extended="true" />
1.数据库管理员系统权限（数据库实体管理部分）<br _extended="true" />
ADUIT ANY<br _extended="true" />
CREATE ANY CLUSTER<br _extended="true" />
ALTER ANY CLUSTER<br _extended="true" />
DROP ANY CLUSTER<br _extended="true" />
CREATE ANY INDEX<br _extended="true" />
ALTER ANY INDEX<br _extended="true" />
DROP ANY INDEX<br _extended="true" />
GRANT ANY PRIVILEGE<br _extended="true" />
CREATE ANY PROCEDURE<br _extended="true" />
ALTER ANY PROCEDURE<br _extended="true" />
DROP ANY PROCEDURE<br _extended="true" />
EXECUTE ANY PROCEDURE<br _extended="true" />
ALTER ANY ROLE<br _extended="true" />
DROP ANY ROLE<br _extended="true" />
GRANT ANY ROLE<br _extended="true" />
CREATE ANY SEQUENCE<br _extended="true" />
ALTER ANY SEQUENCE<br _extended="true" />
DROP ANY SEQUENCE<br _extended="true" />
SELECT ANY SEQUENCE<br _extended="true" />
CREATE ANY SNAPSHOT<br _extended="true" />
ALTER ANY SNAPSHOT<br _extended="true" />
DROP ANY SNAPSHOT<br _extended="true" />
CREATE ANY SYSNONYM<br _extended="true" />
DROP ANY SYSNONYM<br _extended="true" />
CREATE ANY TABLE<br _extended="true" />
ALTER ANY TABLE<br _extended="true" />
DROP ANY TABLE<br _extended="true" />
LOCK ANY TABLE<br _extended="true" />
COMMENT ANY TABLE<br _extended="true" />
SELECT ANY TABLE<br _extended="true" />
INSERT ANY TABLE<br _extended="true" />
UPDATE ANY TABLE<br _extended="true" />
DELETE ANY TABLE<br _extended="true" />
CREATE ANY TRIGGER<br _extended="true" />
ALTER ANY TRIGGER<br _extended="true" />
DROP ANY TRIGGER<br _extended="true" />
CREATE ANY VIEW<br _extended="true" />
DROP ANY VIEW<br _extended="true" />
CREATE ANY TYPE<br _extended="true" />
DROP ANY TYPE<br _extended="true" />
CREATE ANY LIBRARY<br _extended="true" />
DROP ANY LIBRARY</font></p>
<p _extended="true"><font face="宋体" _extended="true">2.数据库管理系统权限(数据库维护部分)<br _extended="true" />
ALTER DATABASE<br _extended="true" />
CREATE PROFILE<br _extended="true" />
ALTER PROFILE<br _extended="true" />
DROP PROFILE<br _extended="true" />
ALTER RESOURCE COST<br _extended="true" />
CREATE PUBLIC DATABASE LINK<br _extended="true" />
DROP PUBLIC DATABASE LINK<br _extended="true" />
CREATE ROLE<br _extended="true" />
CREATE ROLLBACK SEGMENT<br _extended="true" />
ALTER ROLLBACK SEGMENT<br _extended="true" />
DROP ROLLBACK SEGMENT<br _extended="true" />
ALTER SYSTEM<br _extended="true" />
CREATE TABLESPACE<br _extended="true" />
ALTER TABLESPACE<br _extended="true" />
MANAGE TABLESPACE<br _extended="true" />
ALTER USER<br _extended="true" />
DROP USER<br _extended="true" />
CREATE SESSION<br _extended="true" />
CREATE PUBLIC SYNONYM<br _extended="true" />
DROP PUBLIC SYNONYM<br _extended="true" />
UNLIMITED TABLESPACE<br _extended="true" />
CREATE ROLE<br _extended="true" />
DROP ROLE</font></p>
<p _extended="true"><font face="宋体" _extended="true">3.数据库开发用户系统权限表<br _extended="true" />
CREATE CLUSTER<br _extended="true" />
DROP CLUSTER<br _extended="true" />
CREATE PROCEDURE<br _extended="true" />
DROP PROCEDURE<br _extended="true" />
CREATE DATABASE LINK<br _extended="true" />
CREATE SYSNONYM<br _extended="true" />
DROP SYNONYM<br _extended="true" />
CREATE SEQUENCE<br _extended="true" />
CREATE SNAPSHOTP<br _extended="true" />
CREATE TABLE<br _extended="true" />
CREATE VIEW<br _extended="true" />
UNLIMITED TABLESPACE<br _extended="true" />
CREATE TYPE<br _extended="true" />
CREATE LIBRARY</font></p>
<p _extended="true"><font face="宋体" _extended="true">三、系统权限授权命令的使用<br _extended="true" />
　　语法：<br _extended="true" />
GRANT 权限名 TO　用户|角色|PUBLIC<br _extended="true" />
其中，PUBLIC表示将权限赋给数据库中所有的用户<br _extended="true" />
例：赋给用户USER1权限CREATE TABLE的授权命令如下：<br _extended="true" />
SQL&gt;GRANT CREATE TABLE TO USER1;<br _extended="true" />
授权语句还可以增加WITH ADMIN OPTION选项，表示被授权的用户可以将它所得权限赋给其它用户，如：<br _extended="true" />
SQL&gt;GRANT CREATE TABLE,CREATE VIEW TO USER1,USER2 WITH ADMIN OPTION;<br _extended="true" />
若要了解各用户所拥有的系统权限，可以查询数据字典USER_SYS_PRIVS、ROLE_SYS_PRIVS。<br _extended="true" />
若要回收权限，则使用REVOKE命令，如：<br _extended="true" />
SQL&gt;REVOKE CREATE TABLE FROM USER1;</font></p>
<p _extended="true"><font face="宋体" _extended="true">四、实体权限管理<br _extended="true" />
　　实体权限是指某一用户对某一特定schema对象的操作权限。<br _extended="true" />
1.实体权限分类<br _extended="true" />
　　不同的实体类型有不同的实体权限，如下表</font></p>
<p _extended="true"><font face="宋体" _extended="true"><br _extended="true" />
2.实体权限的授命令</font></p>
<p _extended="true">　　语法如下：<br _extended="true" />
GRANT 实体权限名|ALL TO 用户|角色|PUBLIC<br _extended="true" />
其中，ALL表示实体的所有实体权限。<br _extended="true" />
如：<br _extended="true" />
SQL&gt;GRANT SELECT ON BOOKS_QUTHORS TO USER1;<br _extended="true" />
以下语句用来查询表的实体权限的授权信息：<br _extended="true" />
SQL&gt;SELECT * FROM USER_TAB_PRIVES<br _extended="true" />
若要回收实体权限，使用REVOKE,其语法如下：<br _extended="true" />
REVOKE 实体权限名|ALL ON 实体名 FROM 用户名|角色名|PUBLIC。</p>
<img src ="http://www.blogjava.net/jesenblog/aggbug/188243.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jesenblog/" target="_blank">白露</a> 2008-03-24 15:10 <a href="http://www.blogjava.net/jesenblog/articles/188243.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>