﻿<?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-JAVA学习笔记-随笔分类-ORACLE</title><link>http://www.blogjava.net/lingy/category/39870.html</link><description /><language>zh-cn</language><lastBuildDate>Wed, 18 Aug 2010 23:12:54 GMT</lastBuildDate><pubDate>Wed, 18 Aug 2010 23:12:54 GMT</pubDate><ttl>60</ttl><item><title>Oracle DDL,DML,DCL,TCL 基础概念 </title><link>http://www.blogjava.net/lingy/archive/2010/08/17/329116.html</link><dc:creator>林光炎</dc:creator><author>林光炎</author><pubDate>Tue, 17 Aug 2010 08:50:00 GMT</pubDate><guid>http://www.blogjava.net/lingy/archive/2010/08/17/329116.html</guid><description><![CDATA[<h5><a name="DDL">DDL</a></h5>
<br />
Data Definition Language (DDL) statements are used to define the database structure or schema. Some examples:
<ul>
    <li>CREATE - to create objects in the database
    <li>ALTER - alters the structure of the database
    <li>DROP - delete objects from the database
    <li>TRUNCATE - remove all records from a table, including all spaces allocated for the records are removed
    <li>COMMENT - add comments to the data dictionary
    <li>RENAME - rename an object</li>
</ul>
<h5><a name="DML"><br />
DML</a></h5>
<br />
Data Manipulation Language (DML) statements are used for managing data within schema objects. Some examples:
<ul>
    <li>SELECT - retrieve data from the a database
    <li>INSERT - insert data into a table
    <li>UPDATE - updates existing data within a table
    <li>DELETE - deletes all records from a table, the space for the records remain
    <li>MERGE - UPSERT operation (insert or update)
    <li>CALL - call a PL/SQL or Java subprogram
    <li>EXPLAIN PLAN - explain access path to data
    <li>LOCK TABLE - control concurrency</li>
</ul>
<h5><a name="DCL"><br />
DCL</a></h5>
<br />
Data Control Language (DCL) statements. Some examples:
<ul>
    <li>GRANT - gives user's access privileges to database
    <li>REVOKE - withdraw access privileges given with the GRANT command</li>
</ul>
<h5><a name="TCL"><br />
TCL</a></h5>
<br />
Transaction Control (TCL) statements are used to manage the changes made by DML statements. It allows statements to be grouped together into logical transactions.
<ul>
    <li>COMMIT - save work done
    <li>SAVEPOINT - identify a point in a transaction to which you can later roll back
    <li>ROLLBACK - restore database to original since the last COMMIT
    <li>SET TRANSACTION - Change transaction options like isolation level and what rollback segment to use</li>
</ul>
<p><br />
作者：李敬然（Gnie）<br />
出处：<a href="http://www.cnblogs.com/gnielee/">{GnieTech}</a> （http://www.cnblogs.com/gnielee/）<br />
版权声明：本文的版权归作者与博客园共有。转载时须注明本文的详细链接，否则作者将保留追究其法律责任。</p>
<img src ="http://www.blogjava.net/lingy/aggbug/329116.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lingy/" target="_blank">林光炎</a> 2010-08-17 16:50 <a href="http://www.blogjava.net/lingy/archive/2010/08/17/329116.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>oracle 回滚 sql操作</title><link>http://www.blogjava.net/lingy/archive/2010/06/02/322585.html</link><dc:creator>林光炎</dc:creator><author>林光炎</author><pubDate>Wed, 02 Jun 2010 08:31:00 GMT</pubDate><guid>http://www.blogjava.net/lingy/archive/2010/06/02/322585.html</guid><description><![CDATA[select * from ali_zeus_opportunity as of timestamp to_timestamp('2010-6-2 12:00:00','yyyy-mm-dd hh24:mi:ss');<br />
<img src ="http://www.blogjava.net/lingy/aggbug/322585.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lingy/" target="_blank">林光炎</a> 2010-06-02 16:31 <a href="http://www.blogjava.net/lingy/archive/2010/06/02/322585.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>树结构和它的专用函数SYS_CONNECT_BY_PATH</title><link>http://www.blogjava.net/lingy/archive/2009/09/20/295773.html</link><dc:creator>林光炎</dc:creator><author>林光炎</author><pubDate>Sun, 20 Sep 2009 13:32:00 GMT</pubDate><guid>http://www.blogjava.net/lingy/archive/2009/09/20/295773.html</guid><description><![CDATA[简单的树型结构<br />
关于树的普通应用<br />
学习了下这个函数, 用ORGINDUSTRIES的表做了个测试:<br />
正常的树型结构<br />
select lpad(' ',6*(level-1))||industry,indlevel,indid,pindid<br />
from ORGINDUSTRIES<br />
start with indid=1<br />
connect by pindid=prior indid<br />
结果显示如下<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;Indlevel&nbsp;&nbsp;indid&nbsp; &nbsp; pindid<br />
&nbsp; &nbsp; &nbsp; &nbsp; 服装与服饰&nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 1&nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;1&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; 0<br />
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; 服装&nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;2&nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;2&nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;1<br />
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; 女装&nbsp; &nbsp; &nbsp; &nbsp; 3&nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;3&nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;2<br />
<br />
倒型树<br />
下面这个例子是个&#8221;倒数&#8221;—倒过来的树型结构<br />
select lpad(' ',6*(level-1))||industry,indlevel,indid,pindid<br />
from ORGINDUSTRIES<br />
start with indid=20<br />
connect by indid=prior pindid;<br />
这是标准结果:<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;Indlevel indid&nbsp; &nbsp; pindid<br />
二手服装&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; 3&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;20&nbsp; &nbsp;&nbsp; &nbsp; 2<br />
&nbsp; &nbsp;&nbsp; &nbsp;服装&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;2&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;2&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;1<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;服装与服饰&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;1&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;1&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;0<br />
结论<br />
无论正树还是倒树, 关键就在于connect by的条件. <br />
正树:&nbsp;&nbsp;必须是&nbsp;&nbsp;&#8216;父&#8217;= prior &#8216;子&#8217;<br />
倒树:&nbsp;&nbsp;必须是&nbsp;&nbsp;&#8216;子&#8217;= prior &#8216;父&#8217;<br />
<br />
树型结构的条件过滤<br />
采用树型结构的话, 如果我们想将树上的一个分支砍掉.&nbsp;&nbsp;将分支后面的结构都抛弃掉, 这个可以实现麽？当然可以。 但是不是用where， where条件只能去除单一的条件。<br />
所以， 这种树型的过滤条件就需要加在connect by上面。<br />
<br />
测试如下：由于用真实环境比较贴近实际，所以提前用下SYS_CONNECT_BY_PATH函数来显示下环境<br />
<br />
不加任何条件的环境：<br />
select areaname,sys_connect_by_path(areaname,',')<br />
from areas bb<br />
start with areaname='中国大陆'<br />
connect by parentareaid=prior areaid&nbsp;&nbsp;<br />
<br />
结果：<br />
1&nbsp; &nbsp; &nbsp; &nbsp; 中国大陆,中国大陆<br />
2&nbsp; &nbsp; &nbsp; &nbsp; 北京&nbsp; &nbsp; &nbsp; &nbsp; ,中国大陆,北京<br />
3&nbsp; &nbsp; &nbsp; &nbsp; 北京&nbsp; &nbsp; &nbsp; &nbsp; ,中国大陆,北京,北京<br />
4&nbsp; &nbsp; &nbsp; &nbsp; 东城区&nbsp; &nbsp; &nbsp; &nbsp; ,中国大陆,北京,东城区<br />
5&nbsp; &nbsp; &nbsp; &nbsp; 西城区&nbsp; &nbsp; &nbsp; &nbsp; ,中国大陆,北京,西城区<br />
22&nbsp; &nbsp; &nbsp; &nbsp; 广东&nbsp; &nbsp; &nbsp; &nbsp; ,中国大陆,广东<br />
23&nbsp; &nbsp; &nbsp; &nbsp; 广州&nbsp; &nbsp; &nbsp; &nbsp; ,中国大陆,广东,广州<br />
24&nbsp; &nbsp; &nbsp; &nbsp; 汕尾&nbsp; &nbsp; &nbsp; &nbsp; ,中国大陆,广东,汕尾<br />
25&nbsp; &nbsp; &nbsp; &nbsp; 潮阳&nbsp; &nbsp; &nbsp; &nbsp; ,中国大陆,广东,潮阳<br />
46&nbsp; &nbsp; &nbsp; &nbsp; 上海&nbsp; &nbsp; &nbsp; &nbsp; ,中国大陆,上海<br />
47&nbsp; &nbsp; &nbsp; &nbsp; 上海&nbsp; &nbsp; &nbsp; &nbsp; ,中国大陆,上海,上海<br />
48&nbsp; &nbsp; &nbsp; &nbsp; 黄浦区&nbsp; &nbsp; &nbsp; &nbsp; ,中国大陆,上海,黄浦区<br />
49&nbsp; &nbsp; &nbsp; &nbsp; 闸北区&nbsp; &nbsp; &nbsp; &nbsp; ,中国大陆,上海,闸北区<br />
<br />
<br />
加了where过滤条件的SQL:<br />
select areaname,sys_connect_by_path(areaname,',')<br />
from areas bb<br />
where bb.areaid&gt;861000<br />
start with areaname='中国大陆'<br />
connect by parentareaid=prior areaid<br />
<br />
结果为：<br />
2&nbsp; &nbsp; &nbsp; &nbsp; 北京&nbsp; &nbsp; &nbsp; &nbsp; ,中国大陆,北京<br />
3&nbsp; &nbsp; &nbsp; &nbsp; 北京&nbsp; &nbsp; &nbsp; &nbsp; ,中国大陆,北京,北京<br />
4&nbsp; &nbsp; &nbsp; &nbsp; 东城区&nbsp; &nbsp; &nbsp; &nbsp; ,中国大陆,北京,东城区<br />
5&nbsp; &nbsp; &nbsp; &nbsp; 西城区&nbsp; &nbsp; &nbsp; &nbsp; ,中国大陆,北京,西城区<br />
22&nbsp; &nbsp; &nbsp; &nbsp; 广东&nbsp; &nbsp; &nbsp; &nbsp; ,中国大陆,广东<br />
23&nbsp; &nbsp; &nbsp; &nbsp; 广州&nbsp; &nbsp; &nbsp; &nbsp; ,中国大陆,广东,广州<br />
24&nbsp; &nbsp; &nbsp; &nbsp; 汕尾&nbsp; &nbsp; &nbsp; &nbsp; ,中国大陆,广东,汕尾<br />
25&nbsp; &nbsp; &nbsp; &nbsp; 潮阳&nbsp; &nbsp; &nbsp; &nbsp; ,中国大陆,广东,潮阳<br />
46&nbsp; &nbsp; &nbsp; &nbsp; 上海&nbsp; &nbsp; &nbsp; &nbsp; ,中国大陆,上海<br />
47&nbsp; &nbsp; &nbsp; &nbsp; 上海&nbsp; &nbsp; &nbsp; &nbsp; ,中国大陆,上海,上海<br />
48&nbsp; &nbsp; &nbsp; &nbsp; 黄浦区&nbsp; &nbsp; &nbsp; &nbsp; ,中国大陆,上海,黄浦区<br />
49&nbsp; &nbsp; &nbsp; &nbsp; 闸北区&nbsp; &nbsp; &nbsp; &nbsp; ,中国大陆,上海,闸北区<br />
<br />
结论：去掉了&#8220;1&nbsp; &nbsp; &nbsp; &nbsp; 中国大陆,中国大陆&#8221;数据<br />
<br />
加了connect by的过滤条件：<br />
select areaname,sys_connect_by_path(areaname,',')<br />
from areas bb<br />
where bb.areaid&gt;861000<br />
start with areaname='中国大陆'<br />
connect by parentareaid=prior areaid&nbsp;&nbsp;and areaname&lt;&gt;'广东'<br />
<br />
结果为：<br />
2&nbsp; &nbsp; &nbsp; &nbsp; 北京&nbsp; &nbsp; &nbsp; &nbsp; ,中国大陆,北京<br />
3&nbsp; &nbsp; &nbsp; &nbsp; 北京&nbsp; &nbsp; &nbsp; &nbsp; ,中国大陆,北京,北京<br />
4&nbsp; &nbsp; &nbsp; &nbsp; 东城区&nbsp; &nbsp; &nbsp; &nbsp; ,中国大陆,北京,东城区<br />
5&nbsp; &nbsp; &nbsp; &nbsp; 西城区&nbsp; &nbsp; &nbsp; &nbsp; ,中国大陆,北京,西城区<br />
46&nbsp; &nbsp; &nbsp; &nbsp; 上海&nbsp; &nbsp; &nbsp; &nbsp; ,中国大陆,上海<br />
47&nbsp; &nbsp; &nbsp; &nbsp; 上海&nbsp; &nbsp; &nbsp; &nbsp; ,中国大陆,上海,上海<br />
48&nbsp; &nbsp; &nbsp; &nbsp; 黄浦区&nbsp; &nbsp; &nbsp; &nbsp; ,中国大陆,上海,黄浦区<br />
49&nbsp; &nbsp; &nbsp; &nbsp; 闸北区&nbsp; &nbsp; &nbsp; &nbsp; ,中国大陆,上海,闸北区<br />
<br />
结论：去掉了整个广东的分支，&nbsp;&nbsp;在结果集中只有北京和上海<br />
<br />
<br />
SYS_CONNECT_BY_PATH函数<br />
采用SYS_CONNECT_BY_PATH函数为:<br />
<br />
select industry,sys_connect_by_path(industry,'/')<br />
from ORGINDUSTRIES<br />
start with indid=3<br />
connect by indid=prior pindid;<br />
<br />
结果为:<br />
女装&nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;/女装<br />
服装&nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;/女装/服装<br />
服装与服饰&nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;/女装/服装/服装与服饰<br />
<br />
这样的话, 就可以实现, 树结构的结果集的单行拼接:<br />
<br />
我们只需要取最大的字段就OK了<br />
<br />
测试如下：<br />
<br />
select max(sys_connect_by_path(industry,'/'))<br />
from ORGINDUSTRIES<br />
start with indid=3<br />
connect by indid=prior pindid;<br />
<br />
结果为：<br />
/女装/服装/服装与服饰<br />
<br />
<br />
复杂的树型结构――多列变单列<br />
树型结构也分单树和多树(我的称呼,实际上就是指单支和多支)<br />
对于下面的这种情况， 我们必须要构造的树就属于单支树。<br />
原始环境<br />
环境如下：<br />
select * from test；<br />
<br />
结果为：<br />
1&nbsp; &nbsp; &nbsp; &nbsp; n1<br />
1&nbsp; &nbsp; &nbsp; &nbsp; n2<br />
1&nbsp; &nbsp; &nbsp; &nbsp; n3<br />
1&nbsp; &nbsp; &nbsp; &nbsp; n4<br />
1&nbsp; &nbsp; &nbsp; &nbsp; n5<br />
3&nbsp; &nbsp; &nbsp; &nbsp; t1<br />
3&nbsp; &nbsp; &nbsp; &nbsp; t2<br />
3&nbsp; &nbsp; &nbsp; &nbsp; t3<br />
3&nbsp; &nbsp; &nbsp; &nbsp; t4<br />
3&nbsp; &nbsp; &nbsp; &nbsp; t5<br />
3&nbsp; &nbsp; &nbsp; &nbsp; t6<br />
2&nbsp; &nbsp; &nbsp; &nbsp; m1<br />
<br />
造树<br />
脚本如下：<br />
select no,q,<br />
&nbsp; &nbsp;&nbsp; &nbsp; no+row_number() over( order by no) rn,<br />
&nbsp; &nbsp;&nbsp; &nbsp; row_number() over(partition by no order by no) rn1<br />
from test<br />
<br />
结果如下：<br />
No&nbsp;&nbsp;Q&nbsp;&nbsp;RN RN1<br />
1&nbsp; &nbsp; &nbsp; &nbsp; n1&nbsp; &nbsp; &nbsp; &nbsp; 2&nbsp; &nbsp; &nbsp; &nbsp; 1<br />
1&nbsp; &nbsp; &nbsp; &nbsp; n2&nbsp; &nbsp; &nbsp; &nbsp; 3&nbsp; &nbsp; &nbsp; &nbsp; 2<br />
1&nbsp; &nbsp; &nbsp; &nbsp; n3&nbsp; &nbsp; &nbsp; &nbsp; 4&nbsp; &nbsp; &nbsp; &nbsp; 3<br />
1&nbsp; &nbsp; &nbsp; &nbsp; n4&nbsp; &nbsp; &nbsp; &nbsp; 5&nbsp; &nbsp; &nbsp; &nbsp; 4<br />
1&nbsp; &nbsp; &nbsp; &nbsp; n5&nbsp; &nbsp; &nbsp; &nbsp; 6&nbsp; &nbsp; &nbsp; &nbsp; 5<br />
2&nbsp; &nbsp; &nbsp; &nbsp; m1&nbsp; &nbsp; &nbsp; &nbsp; 8&nbsp; &nbsp; &nbsp; &nbsp; 1<br />
3&nbsp; &nbsp; &nbsp; &nbsp; t1&nbsp; &nbsp; &nbsp; &nbsp; 10&nbsp; &nbsp; &nbsp; &nbsp; 1<br />
3&nbsp; &nbsp; &nbsp; &nbsp; t2&nbsp; &nbsp; &nbsp; &nbsp; 11&nbsp; &nbsp; &nbsp; &nbsp; 2<br />
3&nbsp; &nbsp; &nbsp; &nbsp; t3&nbsp; &nbsp; &nbsp; &nbsp; 12&nbsp; &nbsp; &nbsp; &nbsp; 3<br />
3&nbsp; &nbsp; &nbsp; &nbsp; t4&nbsp; &nbsp; &nbsp; &nbsp; 13&nbsp; &nbsp; &nbsp; &nbsp; 4<br />
3&nbsp; &nbsp; &nbsp; &nbsp; t5&nbsp; &nbsp; &nbsp; &nbsp; 14&nbsp; &nbsp; &nbsp; &nbsp; 5<br />
3&nbsp; &nbsp; &nbsp; &nbsp; t6&nbsp; &nbsp; &nbsp; &nbsp; 15&nbsp; &nbsp; &nbsp; &nbsp; 6<br />
<br />
每列的目的是：<br />
RN1列主要的目的是分组， 按照value值&#8216;1&#8217;，我们可以start with使用它。<br />
<br />
RN列主要用来做connect by使用。 实际上它就是我们要的树。<br />
第一个支： 2，3，4，5，6<br />
第二个支： 8<br />
第三个支： 10，11，12，13，14，15<br />
<br />
中间为什么要断掉：7,9&nbsp;&nbsp;目的就是为了区别每个分支。 到后面看具体的SQL，就明白这里的说法了。<br />
<br />
杀手锏<br />
既然我们有了树， 就可以使用树型函数SYS_CONNECT_BY_PATH和connect by啦，来拼接我们所需要的多列值。<br />
<br />
脚本如下：<br />
select no,sys_connect_by_path(q,',')<br />
from (<br />
select no,q,<br />
&nbsp; &nbsp;&nbsp; &nbsp; no+row_number() over( order by no) rn,<br />
&nbsp; &nbsp;&nbsp; &nbsp; row_number() over(partition by no order by no) rn1<br />
from test<br />
)<br />
start with rn1=1<br />
connect by rn-1=prior rn<br />
<br />
结果为：<br />
1&nbsp; &nbsp; &nbsp; &nbsp; ,n1<br />
1&nbsp; &nbsp; &nbsp; &nbsp; ,n1,n2<br />
1&nbsp; &nbsp; &nbsp; &nbsp; ,n1,n2,n3<br />
1&nbsp; &nbsp; &nbsp; &nbsp; ,n1,n2,n3,n4<br />
1&nbsp; &nbsp; &nbsp; &nbsp; ,n1,n2,n3,n4,n5<br />
2&nbsp; &nbsp; &nbsp; &nbsp; ,m1<br />
3&nbsp; &nbsp; &nbsp; &nbsp; ,t1<br />
3&nbsp; &nbsp; &nbsp; &nbsp; ,t1,t2<br />
3&nbsp; &nbsp; &nbsp; &nbsp; ,t1,t2,t3<br />
3&nbsp; &nbsp; &nbsp; &nbsp; ,t1,t2,t3,t4<br />
3&nbsp; &nbsp; &nbsp; &nbsp; ,t1,t2,t3,t4,t5<br />
3&nbsp; &nbsp; &nbsp; &nbsp; ,t1,t2,t3,t4,t5,t6<br />
<br />
终极武器<br />
最终我们要的值，是单列值， 其实想想， 也就是最长的一行咯。 那么就好办了。 我们直接GROUP BY ，然后取MAX值。<br />
脚本如下：<br />
select no,max(sys_connect_by_path(q,','))<br />
from (<br />
select no,q,<br />
&nbsp; &nbsp;&nbsp; &nbsp; no+row_number() over( order by no) rn,<br />
&nbsp; &nbsp;&nbsp; &nbsp; row_number() over(partition by no order by no) rn1<br />
from test<br />
)<br />
start with rn1=1<br />
connect by rn-1=prior rn <br />
group by no<br />
<br />
结果为：<br />
1&nbsp; &nbsp; &nbsp; &nbsp; ,n1,n2,n3,n4,n5<br />
2&nbsp; &nbsp; &nbsp; &nbsp; ,m1<br />
3&nbsp; &nbsp; &nbsp; &nbsp; ,t1,t2,t3,t4,t5,t6<br />
<br />
如果觉得前面的&#8216;，&#8217;不好看，可以使用ltrim去掉。 或者用substr也可以。<br />
如下：<br />
ltrim(max(sys_connect_by_path(q,',')),',')<br />
或者<br />
substr(max(sys_connect_by_path(q,',')),2) <br />
<img src ="http://www.blogjava.net/lingy/aggbug/295773.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lingy/" target="_blank">林光炎</a> 2009-09-20 21:32 <a href="http://www.blogjava.net/lingy/archive/2009/09/20/295773.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>EXECUTE IMMEDIATE用法小解 </title><link>http://www.blogjava.net/lingy/archive/2009/07/16/287019.html</link><dc:creator>林光炎</dc:creator><author>林光炎</author><pubDate>Thu, 16 Jul 2009 11:42:00 GMT</pubDate><guid>http://www.blogjava.net/lingy/archive/2009/07/16/287019.html</guid><description><![CDATA[EXECUTE IMMEDIATE 代替了以前Oracle8i中DBMS_SQL package包.<br />
它解析并马上执行动态的SQL语句或非运行时创建的PL/SQL块.动态创建和执行SQL语句性能超前，EXECUTE IMMEDIATE的目标在于减小企业费用并获得较高的性能，较之以前它相当容易编码.尽管DBMS_SQL仍然可用，但是推荐使用EXECUTE IMMEDIATE,因为它获的收益在包之上。 <br />
<br />
<br />
-- 使用技巧<br />
<br />
<br />
1. EXECUTE IMMEDIATE将不会提交一个DML事务执行，应该显式提交<br />
如果通过EXECUTE IMMEDIATE处理DML命令，<br />
那么在完成以前需要显式提交或者作为EXECUTE IMMEDIATE自己的一部分.<br />
如果通过EXECUTE IMMEDIATE处理DDL命令,它提交所有以前改变的数据<br />
<br />
<br />
2. 不支持返回多行的查询,这种交互将用临时表来存储记录(参照例子如下)或者用REF cursors.<br />
<br />
<br />
3. 当执行SQL语句时，不要用分号，当执行PL/SQL块时，在其尾部用分号.<br />
<br />
<br />
4. 在Oracle手册中，未详细覆盖这些功能。<br />
下面的例子展示了所有用到Execute immediate的可能方面.希望能给你带来方便.<br />
<br />
<br />
5. 对于Forms开发者,当在PL/SQL 8.0.6.3.版本中，Forms 6i不能使用此功能.<br />
<br />
<br />
EXECUTE IMMEDIATE -- 用法例子<br />
<br />
<br />
1. 在PL/SQL运行DDL语句<br />
<br />
<br />
begin<br />
&nbsp;&nbsp; execute immediate 'set role all';<br />
end;<br />
<br />
<br />
2. 给动态语句传值(USING 子句)<br />
<br />
<br />
declare<br />
&nbsp;&nbsp; l_depnam varchar2(20) := 'testing';<br />
&nbsp;&nbsp; l_loc&nbsp;&nbsp;&nbsp;&nbsp; varchar2(10) := 'Dubai';<br />
&nbsp;&nbsp; begin<br />
&nbsp;&nbsp; execute immediate 'insert into dept values&nbsp;&nbsp; (:1, :2, :3)'<br />
&nbsp;&nbsp;&nbsp;&nbsp; using 50, l_depnam, l_loc;<br />
&nbsp;&nbsp; commit;<br />
end;<br />
<br />
<br />
3. 从动态语句检索值(INTO子句)<br />
<br />
<br />
declare<br />
&nbsp;&nbsp; l_cnt&nbsp;&nbsp;&nbsp;&nbsp; varchar2(20);<br />
begin<br />
&nbsp;&nbsp; execute immediate 'select count(1) from emp'<br />
&nbsp;&nbsp;&nbsp;&nbsp; into l_cnt;<br />
&nbsp;&nbsp; dbms_output.put_line(l_cnt);<br />
end;<br />
<br />
<br />
4. 动态调用例程.例程中用到的绑定变量参数必须指定参数类型.<br />
黓认为IN类型,其它类型必须显式指定<br />
<br />
<br />
declare<br />
&nbsp;&nbsp; l_routin&nbsp;&nbsp;&nbsp; varchar2(100) := 'gen2161.get_rowcnt';<br />
&nbsp;&nbsp; l_tblnam&nbsp;&nbsp;&nbsp; varchar2(20) := 'emp';<br />
&nbsp;&nbsp; l_cnt&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; number;<br />
&nbsp;&nbsp; l_status&nbsp;&nbsp;&nbsp; varchar2(200);<br />
begin<br />
&nbsp;&nbsp; execute immediate 'begin ' || l_routin || '(:2, :3, :4); end;'<br />
&nbsp;&nbsp;&nbsp;&nbsp; using in l_tblnam, out l_cnt, in out l_status;<br />
<br />
&nbsp;&nbsp; if l_status != 'OK' then<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dbms_output.put_line('error');<br />
&nbsp;&nbsp; end if;<br />
end;<br />
<br />
<br />
5. 将返回值传递到PL/SQL记录类型;同样也可用%rowtype变量<br />
<br />
<br />
declare<br />
&nbsp;&nbsp; type empdtlrec is record (empno&nbsp;&nbsp; number(4),<br />
&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; ename&nbsp;&nbsp; varchar2(20),<br />
&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; deptno&nbsp;&nbsp; number(2));<br />
&nbsp;&nbsp; empdtl empdtlrec;<br />
begin<br />
&nbsp;&nbsp; execute immediate 'select empno, ename, deptno ' ||<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 'from emp where empno = 7934'<br />
&nbsp;&nbsp;&nbsp;&nbsp; into empdtl;<br />
end;<br />
<br />
<br />
6. 传递并检索值.INTO子句用在USING子句前<br />
<br />
<br />
declare<br />
&nbsp;&nbsp; l_dept&nbsp;&nbsp;&nbsp;&nbsp; pls_integer := 20;<br />
&nbsp;&nbsp; l_nam&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; varchar2(20);<br />
&nbsp;&nbsp; l_loc&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; varchar2(20);<br />
begin<br />
&nbsp;&nbsp; execute immediate 'select dname, loc from dept where deptno = :1'<br />
&nbsp;&nbsp;&nbsp;&nbsp; into l_nam, l_loc<br />
&nbsp;&nbsp;&nbsp;&nbsp; using l_dept ;<br />
end;<br />
<br />
<br />
7. 多行查询选项.对此选项用insert语句填充临时表，<br />
用临时表进行进一步的处理,也可以用REF cursors纠正此缺憾.<br />
<br />
declare<br />
&nbsp;&nbsp; l_sal&nbsp;&nbsp;&nbsp; pls_integer := 2000;<br />
begin<br />
&nbsp;&nbsp; execute immediate 'insert into temp(empno, ename) ' ||<br />
&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; select empno, ename from emp ' ||<br />
&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; where&nbsp;&nbsp; sal &gt; :1'<br />
&nbsp;&nbsp;&nbsp;&nbsp; using l_sal;<br />
&nbsp;&nbsp; commit;<br />
end;<br />
<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 对于处理动态语句,EXECUTE IMMEDIATE 比以前可能用到的更容易并且更高效.<br />
当意图执行动态语句时，适当地处理异常更加重要.应该关注于捕获所有可能的异常.<br />
<div id="MySignature"><strong><em>我是无聊的人，所以做无聊的事情。</em></strong> </div>
<img src ="http://www.blogjava.net/lingy/aggbug/287019.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lingy/" target="_blank">林光炎</a> 2009-07-16 19:42 <a href="http://www.blogjava.net/lingy/archive/2009/07/16/287019.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>使用 TRUNCATE TABLE 删除所有行</title><link>http://www.blogjava.net/lingy/archive/2009/07/16/287018.html</link><dc:creator>林光炎</dc:creator><author>林光炎</author><pubDate>Thu, 16 Jul 2009 11:41:00 GMT</pubDate><guid>http://www.blogjava.net/lingy/archive/2009/07/16/287018.html</guid><description><![CDATA[<div class="topic">
<div class="majorTitle">SQL Server 2008 联机丛书（2009 年 5 月）<!----></div>
<div class="title">使用 TRUNCATE TABLE 删除所有行<!----></div>
<!--content type: DocStudio. Transform: devdiv2mtps.xslt.-->
<div id="mainSection">
<div id="mainBody">
<p><!----></p>

<p>若要删除表中的所有行，则 TRUNCATE TABLE 语句是一种快速、有效的方法。TRUNCATE TABLE 与不含 WHERE 子句的 DELETE 语句类似。但是，TRUNCATE TABLE 速度更快，并且使用更少的系统资源和事务日志资源。</p>
<p>与 DELETE 语句相比，TRUNCATE TABLE 具有以下优点：</p>
<ul>
    <li>所用的事务日志空间较少。<br />
    DELETE 语句每次删除一行，并在事务日志中为所删除的每行记录一个项。TRUNCATE TABLE 通过释放用于存储表数据的数据页来删除数据，并且在事务日志中只记录页释放。<br />
    <li>使用的锁通常较少。<br />
    当使用行锁执行 DELETE 语句时，将锁定表中各行以便删除。TRUNCATE TABLE 始终锁定表和页，而不是锁定各行。<br />
    <li>如无例外，在表中不会留有任何页。<br />
    执行 DELETE 语句后，表仍会包含空页。例如，必须至少使用一个排他 (LCK_M_X) 表锁，才能释放堆中的空表。如果执行删除操作时没有使用表锁，表（堆）中将包含许多空页。对于索引，删除操作会留下一些空页，尽管这些页会通过后台清除进程迅速释放。<br />
    </li>
</ul>
<p>与 DELETE 语句相同，使用 TRUNCATE TABLE 清空的表的定义与其索引和其他关联对象一起保留在数据库中。如果表中包含标识列，该列的计数器将重置为该列定义的种子值。如果未定义种子，则使用默认值 1。若要保留标识计数器，请使用 DELETE。</p>
<div id="ctl00_MTContentSelector1_mainContentContainer_cpe28768" class="MTPS_CollapsibleRegion">
<div id="ctl00_MTContentSelector1_mainContentContainer_cpe28768_h" class="CollapseRegionLink" onclick="applyClick('ctl00_MTContentSelector1_mainContentContainer_cpe28768');"><img style="border-right-width: 0px; border-top-width: 0px; border-bottom-width: 0px; vertical-align: middle; border-left-width: 0px" id="ctl00_MTContentSelector1_mainContentContainer_cpe28768_i" class="LibC_o" src="http://i.technet.microsoft.com/Global/Images/clear.gif"  alt="" />&nbsp;截断大型表 </div>
<div style="display: block" id="ctl00_MTContentSelector1_mainContentContainer_cpe28768_c" class="MTPS_CollapsibleSection"><a id="sectionToggle0"><!----></a>
<p>Microsoft SQL Server 引入一种功能，此功能可删除或截断超过 128 个区的表，而无需同时保留需要删除的所有区的锁。有关详细信息，请参阅<a id="ctl00_MTContentSelector1_mainContentContainer_ctl04" onclick="javascript:Track('ctl00_MTContentSelector1_mainContentContainer_cpe28768_c|ctl00_MTContentSelector1_mainContentContainer_ctl04',this);" href="http://technet.microsoft.com/zh-cn/library/ms177495.aspx">删除并重新生成大型对象</a>。</p>
</div>
</div>
<div id="ctl00_MTContentSelector1_mainContentContainer_cpe28769" class="MTPS_CollapsibleRegion">
<div id="ctl00_MTContentSelector1_mainContentContainer_cpe28769_h" class="CollapseRegionLink" onclick="applyClick('ctl00_MTContentSelector1_mainContentContainer_cpe28769');"><img style="border-right-width: 0px; border-top-width: 0px; border-bottom-width: 0px; vertical-align: middle; border-left-width: 0px" id="ctl00_MTContentSelector1_mainContentContainer_cpe28769_i" class="LibC_o" src="http://i.technet.microsoft.com/Global/Images/clear.gif"  alt="" />&nbsp;示例 </div>
<div style="display: block" id="ctl00_MTContentSelector1_mainContentContainer_cpe28769_c" class="MTPS_CollapsibleSection"><a id="sectionToggle1"><!----></a>
<p>下面的示例删除 <code>JobCandidate</code> 表中的所有数据。在 <code>TRUNCATE TABLE</code> 语句之前和之后使用 <code>SELECT</code> 语句来比较结果。</p>
<div id="ctl00_MTContentSelector1_mainContentContainer_ctl08_other">
<div class="CodeSnippetTitleBar">
<div class="CodeDisplayLanguage"></div>
<div class="CopyCodeButton"><a class="copyCode" title="复制代码" href="javascript:CopyCode('ctl00_MTContentSelector1_mainContentContainer_ctl08other');">
<div class="LibC_copy_off" align="center" border="0" height="9px" width="auto"></div>
复制代码</a></div>
</div>
<div dir="ltr">
<pre style="word-wrap: break-word; word-break: break-all" id="ctl00_MTContentSelector1_mainContentContainer_ctl08other" class="libCScode" space="preserve">USE AdventureWorks;
GO
SELECT COUNT(*) AS BeforeTruncateCount
FROM HumanResources.JobCandidate;
GO
TRUNCATE TABLE HumanResources.JobCandidate;
GO
SELECT COUNT(*) AS AfterTruncateCount
FROM HumanResources.JobCandidate;
GO
</pre>
</div>
</div>
</div>
</div>
<div id="ctl00_MTContentSelector1_mainContentContainer_cpe28770" class="MTPS_CollapsibleRegion">
<div id="ctl00_MTContentSelector1_mainContentContainer_cpe28770_h" class="CollapseRegionLink" onclick="applyClick('ctl00_MTContentSelector1_mainContentContainer_cpe28770');"><img style="border-right-width: 0px; border-top-width: 0px; border-bottom-width: 0px; vertical-align: middle; border-left-width: 0px" id="ctl00_MTContentSelector1_mainContentContainer_cpe28770_i" class="LibC_o" src="http://i.technet.microsoft.com/Global/Images/clear.gif"  alt="" />&nbsp;请参阅 </div>
<div style="display: block" id="ctl00_MTContentSelector1_mainContentContainer_cpe28770_c" class="MTPS_CollapsibleSection"><a id="seeAlsoToggle"><!----></a>
<h4 class="subHeading">概念</h4>
<a id="ctl00_MTContentSelector1_mainContentContainer_ctl17" onclick="javascript:Track('ctl00_MTContentSelector1_mainContentContainer_cpe28770_c|ctl00_MTContentSelector1_mainContentContainer_ctl17',this);" href="http://technet.microsoft.com/zh-cn/library/ms189245.aspx">使用 DELETE 删除行</a><br />
<a id="ctl00_MTContentSelector1_mainContentContainer_ctl18" onclick="javascript:Track('ctl00_MTContentSelector1_mainContentContainer_cpe28770_c|ctl00_MTContentSelector1_mainContentContainer_ctl18',this);" href="http://technet.microsoft.com/zh-cn/library/ms189634.aspx">删除结果集中的行</a><br />
<a id="ctl00_MTContentSelector1_mainContentContainer_ctl19" onclick="javascript:Track('ctl00_MTContentSelector1_mainContentContainer_cpe28770_c|ctl00_MTContentSelector1_mainContentContainer_ctl19',this);" href="http://technet.microsoft.com/zh-cn/library/ms175486.aspx">使用 TOP 限制删除的行</a><br />
<h4 class="subHeading">其他资源</h4>
<a id="ctl00_MTContentSelector1_mainContentContainer_ctl20" onclick="javascript:Track('ctl00_MTContentSelector1_mainContentContainer_cpe28770_c|ctl00_MTContentSelector1_mainContentContainer_ctl20',this);" href="http://technet.microsoft.com/zh-cn/library/ms173790.aspx">DROP TABLE (Transact-SQL)</a><br />
<a id="ctl00_MTContentSelector1_mainContentContainer_ctl21" onclick="javascript:Track('ctl00_MTContentSelector1_mainContentContainer_cpe28770_c|ctl00_MTContentSelector1_mainContentContainer_ctl21',this);" href="http://technet.microsoft.com/zh-cn/library/ms177570.aspx">TRUNCATE TABLE (Transact-SQL)</a><br />
<br />
<h4 class="subHeading">帮助和信息 </h4>
<a id="ctl00_MTContentSelector1_mainContentContainer_ctl22" onclick="javascript:Track('ctl00_MTContentSelector1_mainContentContainer_cpe28770_c|ctl00_MTContentSelector1_mainContentContainer_ctl22',this);" href="http://technet.microsoft.com/zh-cn/library/ms166016.aspx">获取 SQL Server 2008 帮助 </a></div>
</div>
</div>
</div>
</div>
<img src ="http://www.blogjava.net/lingy/aggbug/287018.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lingy/" target="_blank">林光炎</a> 2009-07-16 19:41 <a href="http://www.blogjava.net/lingy/archive/2009/07/16/287018.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>over partition by与group by 的区别</title><link>http://www.blogjava.net/lingy/archive/2009/06/29/284658.html</link><dc:creator>林光炎</dc:creator><author>林光炎</author><pubDate>Mon, 29 Jun 2009 11:04:00 GMT</pubDate><guid>http://www.blogjava.net/lingy/archive/2009/06/29/284658.html</guid><description><![CDATA[<div id="message10586007" class="t_msgfont">各位好！<br />
over partition by 与 group by 都是与统计类函数用，这两个有什么区别呢？<br />
目前我只知道一个这样的区别：<br />
比如有一张表saraly:CREATE TABLE SALARY AS SELECT 'A' NAME,10 DEPT,1000 SALARY FROM DUAL UNION ALL SELECT 'B',10,2000 FROM DUAL UNION ALL SELECT 'C' ,20,1500 FROM DUAL UNION ALL SELECT 'D',20,3000 FROM DUAL UNION ALL<br />
SELECT 'E',10,1000 FROM DUAL;<br />
NAME DEPT SALARY<br />
A&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;10&nbsp; &nbsp;&nbsp;&nbsp;1000<br />
B&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;10&nbsp; &nbsp;&nbsp;&nbsp;2000<br />
C&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;20&nbsp; &nbsp;&nbsp;&nbsp;1500<br />
D&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;20&nbsp; &nbsp;&nbsp;&nbsp;3000<br />
E&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;10&nbsp; &nbsp;&nbsp;&nbsp;1000&nbsp; &nbsp;<br />
用over partition by 我就可以查询到每位员工本来的具体信息和它所在部门的总工资：<br />
select name,dept,salary,sum(salary) over (partition by dept) total_salary from salary;&nbsp;&nbsp;<br />
name&nbsp; &nbsp;&nbsp; &nbsp; dept&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;salary&nbsp; &nbsp;&nbsp; &nbsp;tatal_salary<br />
A&nbsp; &nbsp; &nbsp; &nbsp; 10&nbsp; &nbsp; &nbsp; &nbsp; 1000&nbsp; &nbsp; &nbsp; &nbsp; 4000<br />
B&nbsp; &nbsp; &nbsp; &nbsp; 10&nbsp; &nbsp; &nbsp; &nbsp; 2000&nbsp; &nbsp; &nbsp; &nbsp; 4000<br />
E&nbsp; &nbsp; &nbsp; &nbsp; 10&nbsp; &nbsp; &nbsp; &nbsp; 1000&nbsp; &nbsp; &nbsp; &nbsp; 4000<br />
C&nbsp; &nbsp; &nbsp; &nbsp; 20&nbsp; &nbsp; &nbsp; &nbsp; 1500&nbsp; &nbsp; &nbsp; &nbsp; 4500<br />
D&nbsp; &nbsp; &nbsp; &nbsp; 20&nbsp; &nbsp; &nbsp; &nbsp; 3000&nbsp; &nbsp; &nbsp; &nbsp; 4500<br />
<br />
用goup by 就没办法做到这点，只能查询到每个部门的总工资：<br />
select dept,sum(salary) total_salary from salary group by dept<br />
dept&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;total_salary<br />
10&nbsp; &nbsp; &nbsp; &nbsp; 4000<br />
20&nbsp; &nbsp; &nbsp; &nbsp; 4500<br />
另外over partion by 还可以做到查询每位员工占部门总工资的百分比：<br />
select name,dept,salary,salary*100/sum(salary) over (partition by dept) percent from salary;<br />
<br />
name&nbsp; &nbsp;&nbsp; &nbsp; dept&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;salary&nbsp; &nbsp;&nbsp;&nbsp;percent<br />
A&nbsp; &nbsp; &nbsp; &nbsp; 10&nbsp; &nbsp; &nbsp; &nbsp; 1000&nbsp; &nbsp; &nbsp; &nbsp; 25<br />
B&nbsp; &nbsp; &nbsp; &nbsp; 10&nbsp; &nbsp; &nbsp; &nbsp; 2000&nbsp; &nbsp; &nbsp; &nbsp; 50<br />
E&nbsp; &nbsp; &nbsp; &nbsp; 10&nbsp; &nbsp; &nbsp; &nbsp; 1000&nbsp; &nbsp; &nbsp; &nbsp; 25<br />
C&nbsp; &nbsp; &nbsp; &nbsp; 20&nbsp; &nbsp; &nbsp; &nbsp; 1500&nbsp; &nbsp; &nbsp; &nbsp; 33.3333333333333<br />
D&nbsp; &nbsp; &nbsp; &nbsp; 20&nbsp; &nbsp; &nbsp; &nbsp; 3000&nbsp; &nbsp; &nbsp; &nbsp; 66.6666666666667<br />
用group by 也没办法做到这个.不知道我的理解正不正确，请各位朋友指点，特别是over partition by 与group by 的更多区别请各位一起分享，谢谢！<br />
<br />
20&nbsp; &nbsp; &nbsp; &nbsp; 4500<br />
<br />
</div>
<img src ="http://www.blogjava.net/lingy/aggbug/284658.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lingy/" target="_blank">林光炎</a> 2009-06-29 19:04 <a href="http://www.blogjava.net/lingy/archive/2009/06/29/284658.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Oracle中的NULL（八）</title><link>http://www.blogjava.net/lingy/archive/2009/06/29/284559.html</link><dc:creator>林光炎</dc:creator><author>林光炎</author><pubDate>Mon, 29 Jun 2009 02:59:00 GMT</pubDate><guid>http://www.blogjava.net/lingy/archive/2009/06/29/284559.html</guid><description><![CDATA[<p style="text-indent: 21pt"><span style="font-family: 宋体">最近在论坛上经常看到，很多人提出和<span lang="EN-US">NULL有关的问题。NULL其实是数据库中特有的类型，Oracle中很多容易出现的错误都是和NULL有关的。</span></span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">打算简单的总结一下<span lang="EN-US">NULL的相关知识。</span></span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">这一篇描述一下在<span lang="EN-US">SQL和PLSQL中一些处理NULL的一些问题。</span></span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体" lang="EN-US">Oracle中的NULL（一）：<a href="http://yangtingkun.itpub.net/post/468/244434">http://yangtingkun.itpub.net/post/468/244434</a></span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体" lang="EN-US">Oracle中的NULL（二）：<a href="http://yangtingkun.itpub.net/post/468/245107">http://yangtingkun.itpub.net/post/468/245107</a></span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体" lang="EN-US">Oracle中的NULL（三）：<a href="http://yangtingkun.itpub.net/post/468/245259">http://yangtingkun.itpub.net/post/468/245259</a></span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体" lang="EN-US">Oracle中的NULL（四）：<a href="http://yangtingkun.itpub.net/post/468/245697">http://yangtingkun.itpub.net/post/468/245697</a></span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体" lang="EN-US">Oracle中的NULL（五）：<a href="http://yangtingkun.itpub.net/post/468/247492">http://yangtingkun.itpub.net/post/468/247492</a></span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体" lang="EN-US">Oracle中的NULL（六）：<a href="http://yangtingkun.itpub.net/post/468/251496">http://yangtingkun.itpub.net/post/468/251496</a></span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体" lang="EN-US">Oracle中的NULL（七）：<a href="http://yangtingkun.itpub.net/post/468/258467">http://yangtingkun.itpub.net/post/468/258467</a></span></p>
<p style="text-indent: 21pt"></p>
<br />
<span style="display: none">8\![ Q!x;]$Yf0</span>
<p style="text-indent: 21pt"><span style="font-family: 宋体" lang="EN-US">NULL的最大的特点就是两个NULL是不相等的。如果用等号来判断两个NULL是否相等得到的结果一定是NULL。从唯一约束的特点也可以看到，对于建立了唯一约束的列，Oracle允许插入多个NULL值，这时因为Oracle不认为这些NULL是相等的。</span></p>
<p><span style="font-size: 10.5pt" lang="EN-US"><font face="宋体">SQL&gt; CREATE TABLE T (ID NUMBER, CONSTRAINT UN_T UNIQUE(ID));</font></span></p>
<p><span style="font-size: 10.5pt"><font face="宋体">表已创建。</font></span></p>
<p><span style="font-size: 10.5pt" lang="EN-US"><font face="宋体">SQL&gt; INSERT INTO T VALUES (1);</font></span></p>
<p><span style="font-size: 10.5pt"><font face="宋体">已创建<span lang="EN-US"> 1 行。</span></font></span></p>
<p><span style="font-size: 10.5pt" lang="EN-US"><font face="宋体">SQL&gt; INSERT INTO T VALUES (1);<br />
<span style="display: none">| Pw6I)A#P,x_0</span>INSERT INTO T VALUES (1)<br />
<span style="display: none">+h:w|3~ N0</span>*<br />
<span style="display: none">LCB-P#b{$C0</span>ERROR 位于第 1 行:<br />
<span style="display: none">f9i vJ Y%T0</span>ORA-00001: 违反唯一约束条件 (YANGTK.UN_T)</font></span></p>
<p><span style="font-size: 10.5pt" lang="EN-US"><br />
<span style="display: none">&amp;rSq _0P7QvYN0</span><font face="宋体">SQL&gt; INSERT INTO T VALUES (NULL);</font></span></p>
<p><span style="font-size: 10.5pt"><font face="宋体">已创建<span lang="EN-US"> 1 行。</span></font></span></p>
<p><span style="font-size: 10.5pt" lang="EN-US"><font face="宋体">SQL&gt; INSERT INTO T VALUES (NULL);</font></span></p>
<p><span style="font-size: 10.5pt"><font face="宋体">已创建<span lang="EN-US"> 1 行。</span></font></span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">但是有的时候，<span lang="EN-US">Oracle会认为NULL是相同的，比如在GROUP BY和DISTINCT操作中。这个时候，Oracle会认为所有的NULL都是一类的。</span></span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">还有一种情况，就是在<span lang="EN-US">DECODE函数中。如果表达式为DECODE(COL, NULL, 0, 1)，那么如果COL的值为NULL，Oracle会认为这种情况与第二个参数的NULL值相匹配，会返回0。不过这里只是给人感觉NULL值是相等的，Oracle在实现DECODE函数的时候，仍然是通过IS NULL的方式进行的判断。</span></span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">对于大多数的常用函数来说，如果输入为<span lang="EN-US">NULL，则输出也是NULL。NVL、NVL2、DECODE和||操作是个例外。他们在输入参数为NULL的时候，结果可能不是NULL。不过归结其原因是因为，这些函数都有多个参数，当多个参数不全为NULL时，结果可能不是NULL，如果输入参数均为NULL，那么得到的输出结果也是NULL。</span></span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体" lang="EN-US">NULL还有一个特点，就是一般聚集函数不会处理NULL值。不管是MAX、MIN、AVG还是SUM，这些聚集函数都不会处理NULL。注意这里说的不会处理NULL，是指聚集函数会直接忽略NULL值记录的存在。除非是聚集函数处理的列中包含的全部记录都是NULL，这种情况下，上面这些聚集函数会返回NULL值。</span></p>
<p><span style="font-size: 10.5pt" lang="EN-US"><font face="宋体">SQL&gt; DELETE T WHERE ID = 1;</font></span></p>
<p><span style="font-size: 10.5pt"><font face="宋体">已删除<span lang="EN-US"> 1 行。</span></font></span></p>
<p><span style="font-size: 10.5pt" lang="EN-US"><font face="宋体">SQL&gt; SELECT NVL(TO_CHAR(ID), 'NULL') FROM T;</font></span></p>
<p><span style="font-size: 10.5pt" lang="EN-US"><font face="宋体">NVL(TO_CHAR(ID),'NULL')<span style="display: none">ITPUB个人空间 Z,I Pa;o~)t/Tm7L</span><br />
----------------------------------------<br />
<span style="display: none">L B d-f-A/o*c0</span>NULL<span style="display: none">ITPUB个人空间(C"}5Q5A#L#t</span><br />
NULL</font></span></p>
<p><span style="font-size: 10.5pt" lang="EN-US"><font face="宋体">SQL&gt; SELECT MAX(ID) FROM T;</font></span></p>
<p><span style="font-size: 10.5pt" lang="EN-US"><font face="宋体">MAX(ID)<br />
<span style="display: none">!C Cs"Ys5|'`0</span>----------</font></span></p>
<p><span style="font-size: 10.5pt" lang="EN-US"><br />
<span style="display: none">G_S.c d5mk)O#c0</span><font face="宋体">SQL&gt; SELECT AVG(ID) FROM T;</font></span></p>
<p><span style="font-size: 10.5pt" lang="EN-US"><font face="宋体">AVG(ID)<span style="display: none">ITPUB个人空间*O.Ylk0OU(Oy4Dq$vQr</span><br />
----------</font></span></p>
<p><span style="font-size: 10.5pt" lang="EN-US"><br />
<span style="display: none">RFf+Lf{] y0</span><font face="宋体">SQL&gt; INSERT INTO T VALUES (1);</font></span></p>
<p><span style="font-size: 10.5pt"><font face="宋体">已创建<span lang="EN-US"> 1 行。</span></font></span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">聚集函数中比较特殊的是<span lang="EN-US">COUNT，第一个特殊点是COUNT不会返回NULL值，即使表中没有记录，或者COUNT(COL)中，COL列的记录全为NULL，COUNT也会返回0值而不是NULL。第二个特殊点就是COUNT(*)或COUNT(常量)的形式。这种形式使得COUNT可以计算包含NULL记录在内的记录总数。</span></span></p>
<p><span style="font-size: 10.5pt" lang="EN-US"><font face="宋体">SQL&gt; SELECT COUNT(*), COUNT(1), COUNT('A'), COUNT(ID), COUNT(NULL) FROM T;</font></span></p>
<p><span style="font-size: 10.5pt" lang="EN-US"><font face="宋体">COUNT(*) COUNT(1) COUNT('A') COUNT(ID) COUNT(NULL)<span style="display: none">ITPUB个人空间-NNOH2z</span><br />
---------- ---------- ---------- ---------- -----------<br />
<span style="display: none">;s t:O8t3o.y0t0</span> 3 3 3 1 0</font></span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">最后简单说一下<span lang="EN-US">AVG，AVG(COL)等价于SUM(COL)/COUNT(COL)，不等价于SUM(COL)/COUNT(*)：</span></span></p>
<p><span style="font-size: 10.5pt" lang="EN-US"><font face="宋体">SQL&gt; SELECT AVG(ID), SUM(ID)/COUNT(ID), SUM(ID)/COUNT(*) FROM T;</font></span></p>
<p><span style="font-size: 10.5pt" lang="EN-US"><font face="宋体">AVG(ID) SUM(ID)/COUNT(ID) SUM(ID)/COUNT(*)<br />
<span style="display: none">6~{9O*mL9C7c)p0</span>---------- ----------------- ----------------<br />
<span style="display: none">6@:[S'L&amp;k\&amp;V9{VR0</span> 1 1 .333333333</font></span></p>
<p style="text-indent: 21pt"></p>
<p style="text-indent: 21pt"></p>
<br />
<img src ="http://www.blogjava.net/lingy/aggbug/284559.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lingy/" target="_blank">林光炎</a> 2009-06-29 10:59 <a href="http://www.blogjava.net/lingy/archive/2009/06/29/284559.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>能否按照DECODE条件来COUNT？？？</title><link>http://www.blogjava.net/lingy/archive/2009/06/29/284556.html</link><dc:creator>林光炎</dc:creator><author>林光炎</author><pubDate>Mon, 29 Jun 2009 02:57:00 GMT</pubDate><guid>http://www.blogjava.net/lingy/archive/2009/06/29/284556.html</guid><description><![CDATA[<p>表A &nbsp; <br />
&nbsp; &nbsp; &nbsp; DW &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WP &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; BJ &nbsp; <br />
&nbsp; &nbsp; &nbsp; －－－－－－－－－－－－－－－－ &nbsp; <br />
&nbsp; &nbsp; &nbsp; A &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; M1 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Y &nbsp; <br />
&nbsp; &nbsp; &nbsp; B &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; M2 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; N &nbsp; <br />
&nbsp; &nbsp; &nbsp; C &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; M3 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Y &nbsp; <br />
&nbsp; &nbsp; &nbsp; D &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; M1 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Y &nbsp; <br />
&nbsp; &nbsp; <br />
&nbsp; 我向统计BJ是'Y&#8216;的DW有多少个和总DW多少个？？ &nbsp; <br />
&nbsp; &nbsp; 我用COUNT(DW),COUNT(DECODE(A.BJ,'Y',DW,0)) &nbsp; <br />
&nbsp; 这样不行啊？？ &nbsp; <br />
&nbsp; SQL应该怎么写啊？？？不要用兼套语句，这样太罗嗦了 <span>问题点数：50、回复次数：3</span><a href="http://topic.csdn.net/t/20060422/19/4706359.html#">Top</a> </p>
<div class="tagad"><iframe src="/Include/Board.htm?Tags=" frameborder="0" scrolling="no"></iframe></div>
<h3><strong><a class="anchor" name="r_34342834">1 楼</a>Visual_Studio_Net（打鼠英雄）<input class="user5" title="五级用户 该版得分小于等于5000分，大于2000分" type="button" /></strong><span>回复于 2006-04-22 20:08:49 得分 <em>15</em></span></h3>
<p>SELECT &nbsp; COUNT(DW),SUM(DECODE(BJ,'Y',1,0)) &nbsp; FROM &nbsp; A<a href="http://topic.csdn.net/t/20060422/19/4706359.html#">Top</a></p>
<h3><strong><a class="anchor" name="r_34342852">2 楼</a>chliang315（）<input class="user3" title="三级用户 该版得分小于等于1000分，大于500分" type="button" /></strong><span>回复于 2006-04-22 20:11:32 得分 <em>35</em></span></h3>
<p>可以的 &nbsp; <br />
&nbsp; COUNT(DW),COUNT(DECODE(A.BJ,'Y',DW,null))<a href="http://topic.csdn.net/t/20060422/19/4706359.html#">Top</a></p>
<h3><strong><a class="anchor" name="r_34342979">3 楼</a>bbcboy（烦猪哥哥）<input class="user1" title="一级用户 该版得分小于等于100分" type="button" /></strong><span>回复于 2006-04-22 20:30:58 得分 0 </span></h3>
<p>两位都是好人啊！！ &nbsp; <br />
&nbsp; 非常感谢！！&nbsp;&nbsp;&nbsp;<br />
&nbsp; </p>
<img src ="http://www.blogjava.net/lingy/aggbug/284556.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lingy/" target="_blank">林光炎</a> 2009-06-29 10:57 <a href="http://www.blogjava.net/lingy/archive/2009/06/29/284556.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>oracle trunc()函数的用法</title><link>http://www.blogjava.net/lingy/archive/2009/06/19/283162.html</link><dc:creator>林光炎</dc:creator><author>林光炎</author><pubDate>Fri, 19 Jun 2009 01:39:00 GMT</pubDate><guid>http://www.blogjava.net/lingy/archive/2009/06/19/283162.html</guid><description><![CDATA[<span class="bold"><span class="smalltxt">TRUNC()函數分兩種<img src="http://blog.csdn.net/Emoticons/tongue_smile.gif"  alt="" /><br />
<br />
</span></span>1.TRUNC(for dates)<br />
&nbsp; &nbsp; &nbsp; &nbsp; TRUNC函数为指定元素而截去的日期值。<br />
&nbsp; &nbsp; &nbsp; &nbsp; 其具体的语法格式如下：<br />
&nbsp; &nbsp; &nbsp; &nbsp; TRUNC（date[,fmt]）<br />
&nbsp; &nbsp; &nbsp; &nbsp; 其中：<br />
&nbsp; &nbsp; &nbsp; &nbsp; date&nbsp; &nbsp; &nbsp; &nbsp; 一个日期值<br />
&nbsp; &nbsp; &nbsp; &nbsp; fmt&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 日期格式，该日期将由指定的元素格式所截去。忽略它则由最近的日期截去<br />
&nbsp; &nbsp; &nbsp; &nbsp; 下面是该函数的使用情况：<br />
&nbsp; &nbsp; &nbsp; &nbsp; TRUNC（TO_DATE(&#8217;24-Nov-1999 08:00 pm&#8217;,&#8217;dd-mon-yyyy hh:mi am&#8217;)）<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; =&#8217;24-Nov-1999 12:00:00 am&#8217;<br />
&nbsp; &nbsp; &nbsp; &nbsp; TRUNC（TO_DATE(&#8217;24-Nov-1999 08:37 pm&#8217;,&#8217;dd-mon-yyyy hh:mi am&#8217;,&#8217;hh&#8217;)）&nbsp; &nbsp; &nbsp; &nbsp; =&#8217;24-Nov-1999 08:00:00 am&#8217;<br />
<br />
2.TRUNC(for number)<br />
&nbsp; &nbsp; &nbsp; &nbsp; TRUNC函数返回处理后的数值，其工作机制与ROUND函数极为类似，只是该函数不对指定小数前或后的部分做相应舍入选择处理，而统统截去。<br />
&nbsp; &nbsp; &nbsp; &nbsp; 其具体的语法格式如下<br />
&nbsp; &nbsp; &nbsp; &nbsp; TRUNC（number[,decimals]）<br />
&nbsp; &nbsp; &nbsp; &nbsp; 其中：<br />
&nbsp; &nbsp; &nbsp; &nbsp; number&nbsp; &nbsp; &nbsp; &nbsp; 待做截取处理的数值<br />
&nbsp; &nbsp; &nbsp; &nbsp; decimals&nbsp; &nbsp; &nbsp; &nbsp; 指明需保留小数点后面的位数。可选项，忽略它则截去所有的小数部分<br />
&nbsp; &nbsp; &nbsp; &nbsp; 下面是该函数的使用情况：<br />
&nbsp; &nbsp; &nbsp; &nbsp; TRUNC（89.985，2）=89.98<br />
&nbsp; &nbsp; &nbsp; &nbsp; TRUNC（89.985）=89<br />
&nbsp; &nbsp; &nbsp; &nbsp; TRUNC（89.985，-1）=80<br />
&nbsp; &nbsp; &nbsp; &nbsp; 注意：第二个参数可以为负数，表示为小数点左边指定位数后面的部分截去，即均以0记。 <br />
<img src ="http://www.blogjava.net/lingy/aggbug/283162.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lingy/" target="_blank">林光炎</a> 2009-06-19 09:39 <a href="http://www.blogjava.net/lingy/archive/2009/06/19/283162.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>oracle merge into 的用法详解+实例 </title><link>http://www.blogjava.net/lingy/archive/2009/06/18/283070.html</link><dc:creator>林光炎</dc:creator><author>林光炎</author><pubDate>Thu, 18 Jun 2009 08:10:00 GMT</pubDate><guid>http://www.blogjava.net/lingy/archive/2009/06/18/283070.html</guid><description><![CDATA[<div class="postTitle"><a id="AjaxHolder_ctl01_TitleUrl" class="postTitle2" href="http://www.cnblogs.com/xy6521/articles/1310177.html">oracle merge into 的用法详解+实例</a> </div>
<div class="tit">oracle merge into 的用法详解+实例</div>
<table style="table-layout: fixed">
    <tbody>
        <tr>
            <td>
            <div id="blog_text" class="cnt">
            <p>作用：merge into 解决用B表跟新A表数据，如果A表中没有，则把B表的数据插入A表；</p>
            <p>语法：</p>
            <p><strong>MERGE INTO</strong> [your table-name] [<font color="#0000ff">rename your table here</font>]</p>
            <p><strong>USING</strong> ( [write your query here] )[<font color="#0000ff">rename your query-sql and using just like a table</font>]</p>
            <p><strong>ON</strong> ([conditional expression here] AND [...]...)</p>
            <p><strong>WHEN MATHED THEN</strong> [here you can execute some update sql or something else ]</p>
            <p><strong>WHEN NOT MATHED THEN</strong> [execute something else here ! ]</p>
            <p><font color="#0000ff">-------------------------------------实例-----------------------------------------------------------------</font></p>
            <p>merge into <font color="#0000ff">tfa_alarm_act_nms</font> a<br />
            using (select FP0,FP1,FP2,FP3,REDEFINE_SEVERITY<br />
            from <font color="#0000ff">tfa_alarm_status</font>) b<br />
            on (a.fp0=b.fp0 and a.fp1=b.fp1 and a.fp2=b.fp2 and a.fp3=b.fp3)<br />
            when matched then update set a.redefine_severity=b.redefine_severity<br />
            when not matched then insert (a.fp0,a.fp1,a.fp2,a.fp3,a.org_severity,a.redefine_severity,a.event_time<br />
            ,a.int_id)<br />
            values (b.fp0,b.fp1,b.fp2,b.fp3,b.REDEFINE_SEVERITY,b.redefine_severity,sysdate,7777778);</p>
            <p>作用：利用表<font color="#0000ff"> tfa_alarm_status</font>跟新表<font color="#0000ff">tfa_alarm_act_nms <font color="#000000">的b.redefine_severity</font>，</font><font size="+0">条件是<font color="#0000ff">a.fp0=b.fp0 and a.fp1=b.fp1 and a.fp2=b.fp2 and a.fp3=b.fp3，</font><font color="#000000">如果<font color="#0000ff">tfa_alarm_act_nms</font>表中没有该条件的数据就插入。</font></font></p>
            <p>如果你的数据量很大，此sql效率非常高。</p>
            </div>
            </td>
        </tr>
    </tbody>
</table>
<img src ="http://www.blogjava.net/lingy/aggbug/283070.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lingy/" target="_blank">林光炎</a> 2009-06-18 16:10 <a href="http://www.blogjava.net/lingy/archive/2009/06/18/283070.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>解析：怎样使用Oracle的DECODE()函数 </title><link>http://www.blogjava.net/lingy/archive/2009/06/18/283067.html</link><dc:creator>林光炎</dc:creator><author>林光炎</author><pubDate>Thu, 18 Jun 2009 08:08:00 GMT</pubDate><guid>http://www.blogjava.net/lingy/archive/2009/06/18/283067.html</guid><description><![CDATA[<span id="zoom" class="a14c">&nbsp;
<p style="text-indent: 2em">DECODE()函数，它将输入数值与函数中的参数列表相比较，根据输入值返回一个对应值。函数的参数列表是由若干数值及其对应结果值组成的若干序偶形式。当然，如果未能与任何一个实参序偶匹配成功，则函数也有默认的返回值。
<p style="text-indent: 2em">
<p style="text-indent: 2em">区别于SQL的其它函数，DECODE函数还能识别和操作空值。
<p style="text-indent: 2em">
<p style="text-indent: 2em">语法：DECODE(control_value,value1,result1[,value2,result2&#8230;][,default_result]);
<p style="text-indent: 2em">
<p style="text-indent: 2em">control _value试图处理的数值。DECODE函数将该数值与后面的一系列的偶序相比较，以决定返回值。
<p style="text-indent: 2em">
<p style="text-indent: 2em">value1是一组成序偶的数值。如果输入数值与之匹配成功，则相应的结果将被返回。对应一个空的返回值，可以使用关键字NULL于之对应
<p style="text-indent: 2em">
<p style="text-indent: 2em">result1 是一组成序偶的结果值。
<p style="text-indent: 2em">
<p style="text-indent: 2em">default_result 未能与任何一个值匹配时，函数返回的默认值。
<p style="text-indent: 2em">
<p style="text-indent: 2em">例如：
<p style="text-indent: 2em">
<p style="text-indent: 2em">selectdecode( x , 1 , &#8216;x is 1 &#8217;, 2 , &#8216;x is 2 &#8217;, &#8216;others&#8217;) from dual
<p style="text-indent: 2em">
<p style="text-indent: 2em">当x等于1时，则返回&#8216;x is 1&#8217;。
<p style="text-indent: 2em">
<p style="text-indent: 2em">当x等于2时，则返回&#8216;x is 2&#8217;。
<p style="text-indent: 2em">
<p style="text-indent: 2em">否则，返回others&#8217;。
<p style="text-indent: 2em">
<p style="text-indent: 2em">需要，比较2个值的时候，可以配合SIGN()函数一起使用。
<p style="text-indent: 2em">
<p style="text-indent: 2em">SELECT DECODE( SIGN(5 -6), 1 'Is Positive', -1, 'Is Nagative', 'Is Zero')
<p style="text-indent: 2em">
<p style="text-indent: 2em">同样，也可以用CASE实现：
<p style="text-indent: 2em">
<center><ccid_nobr>
<table border="1" cellspacing="0" bordercolorlight="black" bordercolordark="#ffffff" cellpadding="2" width="400" align="center">
    <tbody>
        <tr>
            <td style="font-size: 9pt" class="code" bgcolor="#e6e6e6">
            <pre><ccid_code>SELECT CASE SIGN(5 - 6)
            WHEN  1  THEN  'Is Positive'
            WHEN　-1 THEN  'Is Nagative'
            ELSE　'Is Zero' END
            FROM DUAL</ccid_code></pre>
            </td>
        </tr>
    </tbody>
</table>
</ccid_nobr></center>
<p style="text-indent: 2em">
<p style="text-indent: 2em">
<p style="text-indent: 2em">
<p style="text-indent: 2em">
<p style="text-indent: 2em">
<p style="text-indent: 2em">此外，还可以在Order by中使用Decode。
<p style="text-indent: 2em">
<p style="text-indent: 2em">例如：表table_subject，有subject_name列。要求按照：语、数、外的顺序进行排序。这时，就可以非常轻松的使用Decode完成要求了。
<p style="text-indent: 2em">
<p style="text-indent: 2em">select * from table_subject order by decode(subject_name, '语文', 1, '数学', 2, , '外语',3)（责任编辑：卢兆林） </p>
</span>
<img src ="http://www.blogjava.net/lingy/aggbug/283067.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lingy/" target="_blank">林光炎</a> 2009-06-18 16:08 <a href="http://www.blogjava.net/lingy/archive/2009/06/18/283067.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>怎样从一个过程返回一个结果集</title><link>http://www.blogjava.net/lingy/archive/2009/06/18/283045.html</link><dc:creator>林光炎</dc:creator><author>林光炎</author><pubDate>Thu, 18 Jun 2009 06:22:00 GMT</pubDate><guid>http://www.blogjava.net/lingy/archive/2009/06/18/283045.html</guid><description><![CDATA[<div>create or replace procedure p_stu_lst(result out sys_refcursor) is<br />
BEGIN<br />
&nbsp; &nbsp;OPEN RESULT FOR SELECT * FROM test;<br />
end p_stu_lst;<br />
SQL&gt; select * from test;<br />
<br />
NAME&nbsp; &nbsp;&nbsp; &nbsp; KM&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;CJ<br />
---------- ---------- ----------<br />
张三&nbsp; &nbsp;&nbsp; &nbsp; 语文&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;80<br />
张三&nbsp; &nbsp;&nbsp; &nbsp; 数学&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;86<br />
张三&nbsp; &nbsp;&nbsp; &nbsp; 英语&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;75<br />
李四&nbsp; &nbsp;&nbsp; &nbsp; 语文&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;78<br />
李四&nbsp; &nbsp;&nbsp; &nbsp; 数学&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;85<br />
李四&nbsp; &nbsp;&nbsp; &nbsp; 英语&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;78<br />
李四&nbsp; &nbsp;&nbsp; &nbsp; 物理&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;90<br />
<br />
已选择7行。<br />
<br />
SQL&gt; exec p_stu_lst(:aaa);<br />
<br />
PL/SQL 过程已成功完成。<br />
<br />
SQL&gt; print aaa<br />
<br />
NAME&nbsp; &nbsp;&nbsp; &nbsp; KM&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;CJ<br />
---------- ---------- ----------<br />
张三&nbsp; &nbsp;&nbsp; &nbsp; 语文&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;80<br />
张三&nbsp; &nbsp;&nbsp; &nbsp; 数学&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;86<br />
张三&nbsp; &nbsp;&nbsp; &nbsp; 英语&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;75<br />
李四&nbsp; &nbsp;&nbsp; &nbsp; 语文&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;78<br />
李四&nbsp; &nbsp;&nbsp; &nbsp; 数学&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;85<br />
李四&nbsp; &nbsp;&nbsp; &nbsp; 英语&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;78<br />
李四&nbsp; &nbsp;&nbsp; &nbsp; 物理&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;90<br />
<br />
已选择7行。</div>
<img src ="http://www.blogjava.net/lingy/aggbug/283045.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lingy/" target="_blank">林光炎</a> 2009-06-18 14:22 <a href="http://www.blogjava.net/lingy/archive/2009/06/18/283045.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Oracle PL/SQL游标的学习</title><link>http://www.blogjava.net/lingy/archive/2009/06/18/283042.html</link><dc:creator>林光炎</dc:creator><author>林光炎</author><pubDate>Thu, 18 Jun 2009 06:11:00 GMT</pubDate><guid>http://www.blogjava.net/lingy/archive/2009/06/18/283042.html</guid><description><![CDATA[<div class="adgg"><a href="http://www.sundns.com/" target="_blank">被过滤广告</a></div>
<strong>一 游标是什么</strong> <br />
<br />
游标字面理解就是游动的光标。 <br />
<br />
用数据库语言来描述：游标是映射在结果集中一行数据上的位置实体，有了游标，用户就可以访问结果集中的任意一行数据了，将游标放置到某行后，即可对该行数据进行操作，例如提取当前行的数据等。 <br />
<br />
<strong>二 游标的分类</strong> <br />
<br />
显式游标和隐式游标 <br />
<br />
显式游标的使用需要4步： <br />
<br />
1. 声明游标 <br />
<br />
<ccid_nobr>
<table border="1" cellspacing="0" bordercolorlight="black" bordercolordark="#ffffff" cellpadding="2" width="400" align="center">
    <tbody>
        <tr>
            <td style="font-size: 9pt" class="code" bgcolor="#e6e6e6">
            <pre><ccid_code>CURSOR mycur(vartype number) is
            select emp_no,emp_zc from cus_emp_basic
            where com_no = vartype;</ccid_code></pre>
            </td>
        </tr>
    </tbody>
</table>
</ccid_nobr><br />
<br />
2. 打开游标 <br />
<br />
open mycur(000627) <br />
<br />
注：000627是参数 <br />
<br />
3. 读取数据 <br />
<br />
fetch mycur into varno, varprice; <br />
<br />
4. 关闭游标 <br />
<br />
close mycur; <br />
<br />
<strong>三 游标的属性</strong> <br />
<br />
oracle 游标有4个属性：%ISOPEN，%FOUND，%NOTFOUND，%ROWCOUNT。 <br />
<br />
%ISOPEN判断游标是否被打开，如果打开%ISOPEN等于true,否则等于false； <br />
<br />
%FOUND %NOTFOUND判断游标所在的行是否有效，如果有效，则%FOUNDD等于true，否则等于false； <br />
<br />
%ROWCOUNT返回当前位置为止游标读取的记录行数。 <br />
<br />
<strong>四 示例</strong> <br />
<br />
<ccid_nobr>
<table border="1" cellspacing="0" bordercolorlight="black" bordercolordark="#ffffff" cellpadding="2" width="400" align="center">
    <tbody>
        <tr>
            <td style="font-size: 9pt" class="code" bgcolor="#e6e6e6">
            <pre><ccid_code>set serveroutput on;
            declare
            varno varchar2(20);
            varprice varchar2(20);
            CURSOR mycur(vartype number) is
            select emp_no,emp_zc from cus_emp_basic
            where com_no = vartype;
            begin
            if mycur%isopen = false then
            open mycur(000627);
            end if;
            fetch mycur into varno,varprice;
            while mycur%found
            loop
            dbms_output.put_line(varno||','||varprice);
            if mycur%rowcount=2 then
            exit;
            end if;
            fetch mycur into varno,varprice;
            end loop;
            close mycur;
            end;</ccid_code></pre>
            </td>
        </tr>
    </tbody>
</table>
</ccid_nobr><br />
<br />
PL/SQL记录的结构和C语言中的结构体类似，是由一组数据项构成的逻辑单元。 <br />
<br />
PL/SQL记录并不保存在数据库中，它与变量一样，保存在内存空间中，在使用记录时候，要首先定义记录结构，然后声明记录变量。可以把PL/SQL记录看作是一个用户自定义的数据类型。 <br />
<br />
<ccid_nobr>
<table border="1" cellspacing="0" bordercolorlight="black" bordercolordark="#ffffff" cellpadding="2" width="400" align="center">
    <tbody>
        <tr>
            <td style="font-size: 9pt" class="code" bgcolor="#e6e6e6">
            <pre><ccid_code>set serveroutput on;
            declare
            type person is record
            (
            empno cus_emp_basic.emp_no%type,
            empzc cus_emp_basic.emp_zc%type);
            person1 person;
            cursor mycur(vartype number)is
            select emp_no,emp_zc from cus_emp_basic
            where com_no=vartype;
            begin
            if mycur%isopen = false then
            open mycur(000627);
            end if;
            loop
            fetch mycur into person1;
            exit when mycur%notfound;
            dbms_output.put_line('雇员编号:'||person1.empno||',地址:'||person1.empzc);
            end loop;
            close mycur;
            end;</ccid_code></pre>
            </td>
        </tr>
    </tbody>
</table>
</ccid_nobr><br />
<br />
典型游标for 循环 <br />
<br />
游标for循环示显示游标的一种快捷使用方式，它使用for循环依次读取结果集中的行数据，当form循环开始时，游标自动打开（不需要open），每循环一次系统自动读取游标当前行的数据（不需要fetch)，当退出for循环时，游标被自动关闭（不需要使用close）。使用游标for循环的时候不能使用open语句，fetch语句和close语句，否则会产生错误。 <br />
<br />
<ccid_nobr>
<table border="1" cellspacing="0" bordercolorlight="black" bordercolordark="#ffffff" cellpadding="2" width="400" align="center">
    <tbody>
        <tr>
            <td style="font-size: 9pt" class="code" bgcolor="#e6e6e6">
            <pre><ccid_code>set serveroutput on;
            declare
            cursor mycur(vartype number)is
            select emp_no,emp_zc from cus_emp_basic
            where com_no=vartype;
            begin
            for person in mycur(000627) loop
            dbms_output.put_line('雇员编号:'||person.emp_no||',地址:'||person.emp_zc);
            end loop;
            end;</ccid_code></pre>
            </td>
        </tr>
    </tbody>
</table>
</ccid_nobr><br />
<img src ="http://www.blogjava.net/lingy/aggbug/283042.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lingy/" target="_blank">林光炎</a> 2009-06-18 14:11 <a href="http://www.blogjava.net/lingy/archive/2009/06/18/283042.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Oracle PL/SQL语言入门</title><link>http://www.blogjava.net/lingy/archive/2009/06/18/283023.html</link><dc:creator>林光炎</dc:creator><author>林光炎</author><pubDate>Thu, 18 Jun 2009 04:37:00 GMT</pubDate><guid>http://www.blogjava.net/lingy/archive/2009/06/18/283023.html</guid><description><![CDATA[<p style="text-indent: 2em"><strong>一、背景介绍</strong>
<p style="text-indent: 2em">　　结构化查询语言(Structured Query Language，简称SQL)是用来访问关系型数据库一种通用语言，属于第四代语言（4GL），其执行特点是非过程化，即不用指明执行的具体方法和途径，而是简单地调用相应语句来直接取得结果即可。显然，这种不关注任何实现细节的语言对于开发者来说有着极大的便利。然而，有些复杂的业务流程要求相应的程序来描述，这种情况下4GL就有些无能为力了。PL/SQL的出现正是为了解决这一问题，PL/SQL是一种过程化语言，属于第三代语言，它与C、C++、Java等语言一样关注于处理细节，可以用来实现比较复杂的业务逻辑。本文主要介绍PL/SQL的编程基础，以使入门者对PL/SQL语言有一个总体认识和基本把握。
<p style="text-indent: 2em"><strong>二、编程基础知识</strong>
<p style="text-indent: 2em">　　1. 程序结构
<p style="text-indent: 2em">　　PL/SQL程序都是以块（block）为基本单位，整个PL/SQL块分三部分：声明部分（用declare开头）、执行部分（以begin开头）和异常处理部分（以exception开头）。其中执行部分是必须的，其他两个部分可选。无论PL/SQL程序段的代码量有多大，其基本结构就是由这三部分组成。如下所示为一段完整的PL/SQL块：
<p style="text-indent: 2em"><ccid_nobr>
<table border="1" cellspacing="0" bordercolorlight="black" bordercolordark="#ffffff" cellpadding="2" width="400" align="center">
    <tbody>
        <tr>
            <td style="font-size: 9pt" class="code" bgcolor="#e6e6e6">
            <pre><ccid_code>/*声明部分，以declare开头*/
            declare v_id integer;
            v_name varchar(20);
            cursor c_emp is select * from employee where emp_id=3;
            /*执行部分，以begin开头*/
            begin 　open c_emp;　　　　　　　　　　　　　//打开游标　
            　　loop　　
            　　　　fetch c_emp into v_id,v_name;　    　//从游标取数据　　
            　　　　exit when c_emp%notfound ;　
            　　end loop ;
            close c_emp;　　　　　　　　　            　 //关闭游标
            dbms_output.PUT_LINE(v_name);
            /*异常处理部分，以exception开始*/
            exception
            　　when no_data_found then
            　　dbms_output.PUT_LINE('没有数据');
            end ;</ccid_code></pre>
            </td>
        </tr>
    </tbody>
</table>
</ccid_nobr>
<p style="text-indent: 2em">　　2. 控制结构
<p style="text-indent: 2em">　　PL/SQL程序段中有三种程序结构：条件结构、循环结构和顺序结构。
<p style="text-indent: 2em">　　1) 条件结构
<p style="text-indent: 2em">　　与其它语言完全类似，语法结构如下：
<p style="text-indent: 2em"><ccid_nobr>
<table border="1" cellspacing="0" bordercolorlight="black" bordercolordark="#ffffff" cellpadding="2" width="400" align="center">
    <tbody>
        <tr>
            <td style="font-size: 9pt" class="code" bgcolor="#e6e6e6">
            <pre><ccid_code>if condition then
            statement1
            else
            statement2
            end if ;</ccid_code></pre>
            </td>
        </tr>
    </tbody>
</table>
</ccid_nobr>　　
<p style="text-indent: 2em">　　2) 循环结构
<p style="text-indent: 2em">　　这一结构与其他语言不太一样，在PL/SQL程序中有三种循环结构：
<p style="text-indent: 2em"><ccid_nobr>
<table border="1" cellspacing="0" bordercolorlight="black" bordercolordark="#ffffff" cellpadding="2" width="400" align="center">
    <tbody>
        <tr>
            <td style="font-size: 9pt" class="code" bgcolor="#e6e6e6">
            <pre><ccid_code>a. loop &#8230; end loop;
            b. while condition loop &#8230; end loop;
            c. for variable in low_bound . . upper_bound loop &#8230; end loop;</ccid_code></pre>
            </td>
        </tr>
    </tbody>
</table>
</ccid_nobr>
<p style="text-indent: 2em">　　其中的&#8220;&#8230;&#8221;代表循环体。
<p style="text-indent: 2em">　　3) 顺序结构
<p style="text-indent: 2em">　　实际就是goto的运用，不过从程序控制的角度来看，尽量少用goto可以使得程序结构更加的清晰。
<p style="text-indent: 2em">　　3. 变量声明与赋值
<p style="text-indent: 2em">　　PL/SQL主要用于数据库编程，所以其所有的数据类型跟Oracle数据库里的字段类型是一一对应的，大体分为数字型、布尔型、字符型和日期型。这里简单介绍两种常用数据类型：number、varchar2。
<p style="text-indent: 2em">　　number
<p style="text-indent: 2em">　　用来存储整数和浮点数。范围为１e130～10e125，其使用语法为：
<p style="text-indent: 2em">　　number[(precision, scale)]
<p style="text-indent: 2em">　　其中(precision, scale)是可选的，precision表示所有数字的个数，scale表示小数点右边数字的个数。
<p style="text-indent: 2em">　　varchar2
<p style="text-indent: 2em">　　用来存储变长的字符串，其使用语法为：
<p style="text-indent: 2em">　　varchar2[(size)]
<p style="text-indent: 2em">　　其中size为可选，表示该字符串所能存储的最大长度。
<p style="text-indent: 2em">　　在PL/SQL中声明变量与其他语言不太一样，它采用从右往左的方式声明，比如声明一个number类型的变量v_id，那其形式应为：
<p style="text-indent: 2em">　　v_id number;
<p style="text-indent: 2em">　　如果给上面的v_id变量赋值，不能用&#8220;=&#8221;，应该用&#8220;:=&#8221;,即形式为：
<p style="text-indent: 2em">　　v_id :=5;
<p style="text-indent: 2em">　　4. SQL基本命令
<p style="text-indent: 2em">　　PL/SQL使用的数据库操作语言还是基于SQL的，所以熟悉SQL是进行PL/SQL编程的基础。SQL语言的分类情况大致如下：
<p style="text-indent: 2em">　　1) 数据定义语言(DDL)：Create，Drop，Grant，Revoke，&#8230;
<p style="text-indent: 2em">　　2) 数据操纵语言(DML)：Update，Insert，Delete，&#8230;
<p style="text-indent: 2em">　　3) 数据控制语言(DCL)：Commit，Rollback，Savapoint，&#8230;
<p style="text-indent: 2em">　　4) 其他：Alter System，Connect，Allocate， &#8230;
<p style="text-indent: 2em">　　具体的语法结构可以参阅其他关于SQL语言的资料，这里不再赘述。
<p style="text-indent: 2em">　　<strong>三、过程与函数</strong>
<p style="text-indent: 2em">　　PL/SQL中的过程和函数与其他语言的过程和函数一样，都是为了执行一定的任务而组合在一起的语句。过程无返回值，函数有返回值。其语法结构为：
<p style="text-indent: 2em">　　过程：Create or replace procedure procname(参数列表) as PL/SQL语句块
<p style="text-indent: 2em">　　函数：Create or replace function funcname(参数列表) return 返回值 as PL/SQL语句块
<p style="text-indent: 2em">　　为便于理解，举例如下：
<p style="text-indent: 2em">　　问题：假设有一张表t1，有f1和f2两个字段，f1为number类型，f2为varchar2类型，要往t1里写两条记录，内容自定。
<p style="text-indent: 2em"><ccid_nobr>
<table border="1" cellspacing="0" bordercolorlight="black" bordercolordark="#ffffff" cellpadding="2" width="400" align="center">
    <tbody>
        <tr>
            <td style="font-size: 9pt" class="code" bgcolor="#e6e6e6">
            <pre><ccid_code>Create or replace procedure test_procedure as
            V_f11 number :=1; /*声明变量并赋初值*/
            V_f12 number :=2;
            V_f21 varchar2(20) :='first';
            V_f22 varchar2(20) :='second';
            Begin
            Insert into t1 values (V_f11, V_f21);
            Insert into t1 values (V_f12, V_f22);
            End test_procedure; /*test_procedure可以省略*/</ccid_code></pre>
            </td>
        </tr>
    </tbody>
</table>
</ccid_nobr>
<p style="text-indent: 2em">　　至此，test_procedure存储过程已经完成，经过编译后就可以在其他PL/SQL块或者过程中调用了。函数与过程具有很大的相似性，此处不再详述。
<p style="text-indent: 2em">　　<strong>四、游标</strong>
<p style="text-indent: 2em">　　游标的定义为：用游标来指代一个DML SQL操作返回的结果集。即当一个对数据库的查询操作返回一组结果集时，用游标来标注这组结果集，以后通过对游标的操作来获取结果集中的数据信息。这里特别提出游标的概念，是因为它在PL/SQL的编程中非常的重要。定义游标的语法结构如下：
<p style="text-indent: 2em">　　cursor cursor_name is SQL语句;
<p style="text-indent: 2em">　　在本文第一段代码中有一句话如下：
<p style="text-indent: 2em">　　cursor c_emp is select * from employee where emp_id=3;
<p style="text-indent: 2em">　　其含义是定义一个游标c_emp，代表employee表中所有emp_id字段为３的结果集。当需要操作该结果集时，必须完成三步：打开游标、使用fetch语句将游标里的数据取出、关闭游标。请参照本文第一段代码的注释理解游标操作的三步骤。
<p style="text-indent: 2em">　　<strong>五、其他概念</strong>
<p style="text-indent: 2em">　　PL/SQL中包的概念很重要，主要是对一组功能相近的过程和函数进行封装，类似于面向对象中的名字空间的概念。
<p style="text-indent: 2em">　　触发器是一种特殊的存储过程，其调用者比较特殊，是当发生特定的事件才被调用，主要用于多表之间的消息通知。
<p style="text-indent: 2em">　　至此，就介绍了PL/SQL的编程基础知识，至于实际的应用，以后接着探讨。 </p>
<img src ="http://www.blogjava.net/lingy/aggbug/283023.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lingy/" target="_blank">林光炎</a> 2009-06-18 12:37 <a href="http://www.blogjava.net/lingy/archive/2009/06/18/283023.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>PL/SQL教程(转)</title><link>http://www.blogjava.net/lingy/archive/2009/06/18/283012.html</link><dc:creator>林光炎</dc:creator><author>林光炎</author><pubDate>Thu, 18 Jun 2009 03:51:00 GMT</pubDate><guid>http://www.blogjava.net/lingy/archive/2009/06/18/283012.html</guid><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 课程 一 PL/SQL 基本查询与排序本课重点：&nbsp;&nbsp; 1、写SELECT语句进行数据库查询&nbsp;&nbsp; 2、进行数学运算&nbsp;&nbsp; 3、处理空值&nbsp;&nbsp; 4、使用别名ALIASES&nbsp;&nbsp; 5、连接列&nbsp;&nbsp; 6、在SQL PLUS中编辑缓冲，修改SQL SCRIPTS&n...&nbsp;&nbsp;<a href='http://www.blogjava.net/lingy/archive/2009/06/18/283012.html'>阅读全文</a><img src ="http://www.blogjava.net/lingy/aggbug/283012.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lingy/" target="_blank">林光炎</a> 2009-06-18 11:51 <a href="http://www.blogjava.net/lingy/archive/2009/06/18/283012.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>oracle 存储过程的基本语法</title><link>http://www.blogjava.net/lingy/archive/2009/06/18/282994.html</link><dc:creator>林光炎</dc:creator><author>林光炎</author><pubDate>Thu, 18 Jun 2009 02:43:00 GMT</pubDate><guid>http://www.blogjava.net/lingy/archive/2009/06/18/282994.html</guid><description><![CDATA[<div class="postbody">
<h1>oracle 存储过程的基本语法</h1>
<p><strong><br />
1.基本结构</strong> <br />
CREATE OR REPLACE PROCEDURE 存储过程名字<br />
(<br />
&nbsp;&nbsp;&nbsp; 参数1 IN NUMBER,<br />
&nbsp;&nbsp;&nbsp; 参数2 IN NUMBER<br />
) IS<br />
变量1 INTEGER :=0;<br />
变量2 DATE;<br />
BEGIN</p>
<p>END 存储过程名字<br />
<br />
<strong>2.SELECT INTO STATEMENT</strong><br />
&nbsp; 将select查询的结果存入到变量中，可以同时将多个列存储多个变量中，必须有一条<br />
&nbsp; 记录，否则抛出异常(如果没有记录抛出NO_DATA_FOUND)<br />
&nbsp; 例子： <br />
&nbsp; BEGIN<br />
&nbsp; SELECT col1,col2 into 变量1,变量2 FROM typestruct where xxx;<br />
&nbsp; EXCEPTION<br />
&nbsp; WHEN NO_DATA_FOUND THEN<br />
&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;xxxx;<br />
&nbsp; END;<br />
&nbsp; ...<br />
<br />
<strong>3.IF 判断</strong><br />
&nbsp; IF V_TEST=1 THEN<br />
&nbsp;&nbsp;&nbsp; BEGIN <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; do something<br />
&nbsp;&nbsp;&nbsp; END;<br />
&nbsp; END IF;<br />
<br />
<strong>4.while 循环</strong><br />
&nbsp; WHILE V_TEST=1 LOOP<br />
&nbsp; BEGIN<br />
&nbsp;XXXX<br />
&nbsp; END;<br />
&nbsp; END LOOP;<br />
<strong><br />
5.变量赋值<br />
</strong>&nbsp; V_TEST := 123;<br />
<strong><br />
6.用for in 使用cursor</strong><br />
&nbsp; ...<br />
&nbsp; IS<br />
&nbsp; CURSOR cur IS SELECT * FROM xxx;<br />
&nbsp; BEGIN<br />
&nbsp;FOR cur_result in cur LOOP<br />
&nbsp;&nbsp;BEGIN<br />
&nbsp;&nbsp;&nbsp;V_SUM :=cur_result.列名1+cur_result.列名2<br />
&nbsp;&nbsp;END;<br />
&nbsp;END LOOP;<br />
&nbsp; END;<br />
<br />
<strong>7.带参数的cursor</strong><br />
&nbsp; CURSOR C_USER(C_ID NUMBER) IS SELECT NAME FROM USER WHERE TYPEID=C_ID;<br />
&nbsp; OPEN C_USER(变量值);<br />
&nbsp; LOOP<br />
&nbsp;FETCH C_USER INTO V_NAME;<br />
&nbsp;EXIT FETCH C_USER%NOTFOUND;<br />
&nbsp;&nbsp;&nbsp; do something<br />
&nbsp; END LOOP;<br />
&nbsp; CLOSE C_USER;<br />
<br />
<strong>8.用pl/sql developer debug<br />
</strong>&nbsp; 连接数据库后建立一个Test WINDOW<br />
&nbsp; 在窗口输入调用SP的代码,F9开始debug,CTRL+N单步调试</p>
</div>
<img src ="http://www.blogjava.net/lingy/aggbug/282994.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lingy/" target="_blank">林光炎</a> 2009-06-18 10:43 <a href="http://www.blogjava.net/lingy/archive/2009/06/18/282994.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>oracle 绑定变量(bind variable)</title><link>http://www.blogjava.net/lingy/archive/2009/06/15/282426.html</link><dc:creator>林光炎</dc:creator><author>林光炎</author><pubDate>Mon, 15 Jun 2009 11:20:00 GMT</pubDate><guid>http://www.blogjava.net/lingy/archive/2009/06/15/282426.html</guid><description><![CDATA[<div class="asset-body">
<div align="center"></div>
oracle 中，对于一个提交的sql语句,存在两种可选的解析过程, 一种叫做硬解析,一种叫做软解析.<br />
一个硬解析需要经解析,制定执行路径,优化访问计划等许多的步骤.硬解释不仅仅耗费大量的cpu，更重要的是会占据重要的们闩（latch）资源，严重的影响系统的规模的扩大（即限制了系统的并发行）， 而且引起的问题不能通过增加内存条和cpu的数量来解决。 </div>
<div id="more" class="asset-more">之所以这样是因为门闩是为了顺序访问以及修改一些内存区域而设置的，这些内存区域是不能被同时修改。当一个sql语句提交后，oracle会首先检查一下共享缓冲池（shared pool）里有没有与之完全相同的语句，如果有的话只须执行软分析即可，否则就得进行硬分析。<br />
而唯一使得oracle 能够重复利用执行计划的方法就是采用绑定变量。绑定变量的实质就是用于替代sql语句中的常量的替代变量。绑定变量能够使得每次提交的sql语句都完全一样。<br />
普通sql语句：<br />
<blockquote style="margin-right: 0px" dir="ltr">
<p>SELECT fname, lname, pcode FROM cust WHERE id = 674;<br />
SELECT fname, lname, pcode FROM cust WHERE id = 234;<br />
SELECT fname, lname, pcode FROM cust WHERE id = 332;<br />
含绑定变量的sql 语句：<br />
SELECT fname, lname, pcode FROM cust WHERE id = :cust_no;</p>
<p>Sql*plus 中使用绑定变量：<br />
sql&gt; variable x number;<br />
sql&gt; exec :x := 123;<br />
sql&gt; SELECT fname, lname, pcode FROM cust WHERE id =:x;</p>
<p>&nbsp;</p>
</blockquote><font style="font-size: 1.25em"><strong>pl/sql</strong></font><br />
pl/sql很多时候都会自动绑定变量而无需编程人员操心，即很多你写得sql语句都会自动利用绑定变量，如下例所示：
<blockquote style="margin-right: 0px" dir="ltr">
<p><br />
create or replace procedure dsal(p_empno in number)<br />
as<br />
begin<br />
update emp<br />
set sal=sal*2<br />
where empno = p_empno;<br />
commit;<br />
end;<br />
/<br />
</p>
</blockquote>也许此时你会想要利用绑定变量来替代p_empno,但是这是完全没有必要的，因为在pl/sql中，引用变量即是引用绑定变量。<br />
但是在pl/sql中动态sql并不是这样。<br />
在vb，java以及其他应用程序中都得显式地利用绑定变量。<br />
对于绑定变量的支持不仅仅限于oracle,其他RDBMS向SQLＳＥＲＶＥＲ也支持这一特性。<br />
但是并不是任何情况下都需要使用绑定变量，　下面是两种例外情况：<br />
1．对于隔相当一段时间才执行一次的ｓｑｌ语句，这是利用绑定变量的好处会被不能有效利用优化器而抵消<br />
2．数据仓库的情况下。</div>
<img src ="http://www.blogjava.net/lingy/aggbug/282426.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lingy/" target="_blank">林光炎</a> 2009-06-15 19:20 <a href="http://www.blogjava.net/lingy/archive/2009/06/15/282426.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>如何得到一个存储过程的创建脚本</title><link>http://www.blogjava.net/lingy/archive/2009/05/27/278279.html</link><dc:creator>林光炎</dc:creator><author>林光炎</author><pubDate>Wed, 27 May 2009 15:21:00 GMT</pubDate><guid>http://www.blogjava.net/lingy/archive/2009/05/27/278279.html</guid><description><![CDATA[<p>1，如何得到一个存储过程的创建脚本<br />
查询数据字典：user_source 和 dba_source<br />
SQL&gt;select text from dba_source where name='p_******' and type='PROCEDURE';</p>
<p>2，如何得到数据库中无效的存储过程<br />
查询数据字典：dba_objects<br />
SQL&gt; select object_name from dba_objects where object</p>
<img src ="http://www.blogjava.net/lingy/aggbug/278279.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lingy/" target="_blank">林光炎</a> 2009-05-27 23:21 <a href="http://www.blogjava.net/lingy/archive/2009/05/27/278279.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Oracle function 集 </title><link>http://www.blogjava.net/lingy/archive/2009/05/26/277972.html</link><dc:creator>林光炎</dc:creator><author>林光炎</author><pubDate>Tue, 26 May 2009 03:11:00 GMT</pubDate><guid>http://www.blogjava.net/lingy/archive/2009/05/26/277972.html</guid><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: oracle的函數很多﹐特整理出來﹕abs(m)&#160;&#160;m的绝对值mod(m,n)&#160;m被n除后的余数power(m,n)&#160;m的n次方round(m[,n])&#160;m四舍五入至小数点后n位的值（n缺省为0）trunc(m[,n])&#160;m截断n位小数位的值（n缺省为0）字符函数：initcap(st)&#160;返回st将每个单词的首字母大写，所有其他...&nbsp;&nbsp;<a href='http://www.blogjava.net/lingy/archive/2009/05/26/277972.html'>阅读全文</a><img src ="http://www.blogjava.net/lingy/aggbug/277972.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lingy/" target="_blank">林光炎</a> 2009-05-26 11:11 <a href="http://www.blogjava.net/lingy/archive/2009/05/26/277972.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>