﻿<?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-依然Fantasy-随笔分类-Oracle</title><link>http://www.blogjava.net/michaelcao/category/37255.html</link><description>我的又一博</description><language>zh-cn</language><lastBuildDate>Tue, 13 Jan 2009 15:23:44 GMT</lastBuildDate><pubDate>Tue, 13 Jan 2009 15:23:44 GMT</pubDate><ttl>60</ttl><item><title>Oracle中返回结果集的存储过程</title><link>http://www.blogjava.net/michaelcao/archive/2009/01/13/251189.html</link><dc:creator>依然Fantasy</dc:creator><author>依然Fantasy</author><pubDate>Tue, 13 Jan 2009 13:55:00 GMT</pubDate><guid>http://www.blogjava.net/michaelcao/archive/2009/01/13/251189.html</guid><wfw:comment>http://www.blogjava.net/michaelcao/comments/251189.html</wfw:comment><comments>http://www.blogjava.net/michaelcao/archive/2009/01/13/251189.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/michaelcao/comments/commentRss/251189.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/michaelcao/services/trackbacks/251189.html</trackback:ping><description><![CDATA[<p>google了一篇不错的例子，加了点注解，这样看起来更方便了：）</p>
<p>Oracle不像SQLServer那样在存储过程中用Select就可以返回结果集，而是通过Out型的参数进行结果集返回的。实际上是利用REF CURSOR</p>
<p><strong>--procedure返回记录集：</strong></p>
<p>----------------------声明一个Package--------------
<br />
CREATE OR REPLACE PACKAGE pkg_test
<br />
AS
<br />
TYPE <span style="color: rgb(0, 0, 255);">myrctype</span> IS REF CURSOR;
<br />
<br />
PROCEDURE get (p_id NUMBER, <span style="color: rgb(0, 0, 255);">p_rc OUT myrctype</span>); --Package中声明名为get 的Procedure(只有接口没内容)</p>
<p>END pkg_test;</p>
<p>--------------------------------------------------------</p>
<p><br />
-----------------声明Package Body，即上面Package中的内容，包括Procedure get---------------------
<br />
CREATE OR REPLACE PACKAGE BODY pkg_test
<br />
AS
<br />
PROCEDURE get (p_id NUMBER, <span style="color: rgb(0, 0, 255);">p_rc OUT myrctype</span>)
<br />
IS
<br />
sqlstr VARCHAR2 (500);
<br />
BEGIN
<br />
IF p_id = 0 THEN
<br />
OPEN p_rc FOR
<br />
SELECT ID, NAME, sex, address, postcode, birthday
<br />
FROM student;
<br />
ELSE
<br />
sqlstr :=
<br />
'select id,name,sex,address,postcode,birthday
<br />
from student where id=<span style="color: rgb(0, 0, 255);">:w_id</span>'; --w_id是个参数，</p>
<p><span style="color: rgb(0, 0, 255);">--以下 p_rc是个</span><span style="color: rgb(0, 0, 0);">REF CURSOR</span><span style="color: rgb(0, 0, 255);">游标类型，而且是OUT型参数，即可返回一个记录集了。USING p_id就是替换上面SQL中:w_id值拉:)</span>
<br />
<span style="color: rgb(0, 0, 255);">OPEN p_rc FOR sqlstr USING p_id;　</span></p>
<p>END IF;
<br />
END get;
<br />
END pkg_test;
<br />
<br />
<br />
<strong>--function返回记录集的例子，原理和上面相同，而是用function的return值来返回记录集。</strong></p>
<p>函数返回记录集:
<br />
建立带ref cursor定义的包和包体及函数：
<br />
CREATE OR REPLACE
<br />
package pkg_test as
<br />
/* 定义ref cursor类型
<br />
不加return类型，为弱类型，允许动态sql查询，
<br />
否则为强类型，无法使用动态sql查询;
<br />
*/
<br />
type myrctype is ref cursor;
<br />
function get(intID number) return myrctype;
<br />
end pkg_test;
<br />
/</p>
<p>CREATE OR REPLACE
<br />
package body pkg_test as
<br />
--函数体
<br />
function get(intID number) return myrctype is
<br />
rc myrctype; --定义ref cursor变量
<br />
sqlstr varchar2(500);
<br />
begin
<br />
if intID=0 then
<br />
--静态测试，直接用select语句直接返回结果
<br />
open rc for select id,name,sex,address,postcode,birthday from student;
<br />
else
<br />
--动态sql赋值，用:w_id来申明该变量从外部获得
<br />
sqlstr := 'select id,name,sex,address,postcode,birthday from student where id=:w_id';
<br />
--动态测试，用sqlstr字符串返回结果，用using关键词传递参数
<br />
open rc for sqlstr using intid;
<br />
end if;</p>
<p>return rc;
<br />
end get;</p>
<p>end pkg_test;</p>
<img src ="http://www.blogjava.net/michaelcao/aggbug/251189.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/michaelcao/" target="_blank">依然Fantasy</a> 2009-01-13 21:55 <a href="http://www.blogjava.net/michaelcao/archive/2009/01/13/251189.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>在ORACLE存储过程中创建临时表</title><link>http://www.blogjava.net/michaelcao/archive/2009/01/13/251185.html</link><dc:creator>依然Fantasy</dc:creator><author>依然Fantasy</author><pubDate>Tue, 13 Jan 2009 13:23:00 GMT</pubDate><guid>http://www.blogjava.net/michaelcao/archive/2009/01/13/251185.html</guid><wfw:comment>http://www.blogjava.net/michaelcao/comments/251185.html</wfw:comment><comments>http://www.blogjava.net/michaelcao/archive/2009/01/13/251185.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/michaelcao/comments/commentRss/251185.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/michaelcao/services/trackbacks/251185.html</trackback:ping><description><![CDATA[<p>在ORACLE存储过程中创建临时表
<br />
</p>
<p><span style="color: rgb(0, 0, 255);">存储过程里不能直接使用DDL语句，所以只能使用动态SQL语句来执行</span></p>
<p>--ON COMMIT DELETE ROWS 说明临时表是事务指定，每次提交后ORACLE将截断表（删除全部行）
<br />
--ON COMMIT PRESERVE ROWS 说明临时表是会话指定，当中断会话时ORACLE将截断表。</p>
<p><br />
CREATE OR REPLACE PROCEDURE temptest
<br />
(p_searchDate IN DATE)
<br />
IS
<br />
v_count INT;
<br />
str varchar2(300);
<br />
BEGIN
<br />
v_count := 0;
<br />
str:='drop table SETT_DAILYTEST';
<br />
execute immediate str;
<br />
str:='CREATE GLOBAL TEMPORARY TABLE SETT_DAILYTEST (
<br />
NACCOUNTID NUMBER not null,
<br />
NSUBACCOUNTID NUMBER not null)
<br />
ON COMMIT PRESERVE ROWS';
<br />
<span style="color: rgb(0, 0, 255);">execute immediate str; ----使用动态SQL语句来执行</span>
<br />
str:='insert into SETT_DAILYTEST (select naccountid,nsubaccountid from sett_dailyaccountbalance)';
<br />
<span style="color: rgb(0, 0, 255);">execute immediate str;</span>
<br />
END temptest;</p>
<p>上面建立一个临时表的存储过程</p>
<p>下面是执行一些操作,向临时表写数据。</p>
<p>CREATE OR REPLACE PROCEDURE PR_DAILYCHECK
<br />
(
<br />
p_Date IN DATE,
<br />
p_Office IN INTEGER,
<br />
p_Currency IN INTEGER,
<br />
P_Check IN INTEGER,
<br />
p_countNum OUT INTEGER)
<br />
IS
<br />
v_count INT;
<br />
BEGIN
<br />
v_count := 0;
<br />
IF p_Date IS NULL THEN
<br />
dbms_output.put_line('日期不能为空');
<br />
ELSE
<br />
IF P_Check = 1 THEN
<br />
<span style="color: rgb(0, 0, 255);">insert into SETT_DAILYTEST (select naccountid,nsubaccountid from sett_dailyaccountbalance
<br />
where dtdate = p_Date);</span>
<br />
select
<br />
count(sd.naccountid) into v_count
<br />
from sett_subaccount ss,sett_account sa,sett_dailytest sd
<br />
where sd.naccountid = sa.id and sd.nsubaccountid = ss.id and sa.id = ss.naccountid
<br />
AND sa.nofficeid = p_Office AND sa.ncurrencyid = p_Currency
<br />
and rownum &lt; 2;
<br />
COMMIT;
<br />
p_countNum := v_count;
<br />
dbms_output.put_line(p_countNum);
<br />
END IF;
<br />
IF P_Check = 2 THEN
<br />
<span style="color: rgb(0, 0, 255);">insert into SETT_DAILYTEST (select naccountid,nsubaccountid from sett_dailyaccountbalance
<br />
where dtdate = p_Date);</span>
<br />
select
<br />
count(sd.naccountid) into v_count
<br />
from sett_cfsubaccount ss,sett_account sa,sett_dailytest sd
<br />
where sd.naccountid = sa.id and sd.nsubaccountid = ss.id and sa.id = ss.naccountid
<br />
AND sa.nofficeid = p_Office AND sa.ncurrencyid = p_Currency
<br />
and rownum &lt; 2;
<br />
COMMIT;
<br />
p_countNum := v_count;
<br />
dbms_output.put_line(p_countNum);
<br />
END IF;
<br />
END IF;
<br />
END PR_DAILYCHECK;</p>
<img src ="http://www.blogjava.net/michaelcao/aggbug/251185.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/michaelcao/" target="_blank">依然Fantasy</a> 2009-01-13 21:23 <a href="http://www.blogjava.net/michaelcao/archive/2009/01/13/251185.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Oracle:PL/SQL 中如何使用Array</title><link>http://www.blogjava.net/michaelcao/archive/2009/01/13/251183.html</link><dc:creator>依然Fantasy</dc:creator><author>依然Fantasy</author><pubDate>Tue, 13 Jan 2009 13:07:00 GMT</pubDate><guid>http://www.blogjava.net/michaelcao/archive/2009/01/13/251183.html</guid><wfw:comment>http://www.blogjava.net/michaelcao/comments/251183.html</wfw:comment><comments>http://www.blogjava.net/michaelcao/archive/2009/01/13/251183.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/michaelcao/comments/commentRss/251183.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/michaelcao/services/trackbacks/251183.html</trackback:ping><description><![CDATA[<p>Oracle本身没数组的概念，但是通过Oracle的Collections和Records类型可以模仿出单维数组和多维数组。</p>
<p>请参考&lt;&lt;Oracle PL/SQL Programming&gt;&gt; Chapter 11、Chapter 12。</p>
<p><br />
---------------------- <strong>单维数组</strong> ------------------------
<br />
DECLARE
<br />
TYPE emp_ssn_array IS TABLE OF NUMBER INDEX BY BINARY_INTEGER; ----注：声明一个Collection
<br />
<br />
best_employees emp_ssn_array;
<br />
worst_employees emp_ssn_array;
<br />
<br />
BEGIN
<br />
best_employees(1) := '123456';
<br />
best_employees(2) := '888888';
<br />
<br />
worst_employees(1) := '222222';
<br />
worst_employees(2) := '666666';
<br />
<br />
FOR i IN 1..best_employees.count LOOP
<br />
DBMS_OUTPUT.PUT_LINE('i='|| i || ', best_employees= ' ||best_employees(i)
<br />
|| ', worst_employees= ' ||worst_employees(i));
<br />
END LOOP;
<br />
<br />
END;</p>
<p><br />
<br />
---------------------- <strong>多维数组</strong> ------------------------
<br />
</p>
<p class="code">DECLARE
<br />
<br />
TYPE emp_type IS RECORD ---------注：声明一个Record类型　emp_type
<br />
( emp_id employee_table.emp_id%TYPE, 　　　　　　　　　　----Record类型中的成员...
<br />
emp_name employee_table.emp_name%TYPE,
<br />
emp_gender employee_table.emp_gender%TYPE );
<br />
<br />
TYPE emp_type_array IS TABLE OF ----注：声明一个Collection类型 emp_type_array ，其中元素为emp_type类型
<br />
emp_type INDEX BY BINARY_INTEGER;
<br />
<br />
emp_rec_array emp_type_array;
<br />
emp_rec emp_type;
<br />
<br />
BEGIN
<br />
emp_rec.emp_id := 300000000;
<br />
emp_rec.emp_name := 'Barbara';
<br />
emp_rec.emp_gender := 'Female';
<br />
<br />
emp_rec_array(1) := emp_rec;
<br />
<br />
emp_rec.emp_id := 300000008;
<br />
emp_rec.emp_name := 'Rick';
<br />
emp_rec.emp_gender := 'Male';
<br />
<br />
emp_rec_array(2) := emp_rec;
<br />
<br />
FOR i IN 1..emp_rec_array.count LOOP
<br />
DBMS_OUTPUT.PUT_LINE('i='||i
<br />
||', emp_id ='||emp_rec_array(i).emp_id
<br />
||', emp_name ='||emp_rec_array(i).emp_name
<br />
||', emp_gender = '||emp_rec_array(i).emp_gender);
<br />
END LOOP;
<br />
<br />
END;
<br />
-------------- Result --------------
<br />
i=1, emp_id =300000000, emp_name =Barbara, emp_gender = Female
<br />
i=2, emp_id =300000008, emp_name =Rick, emp_gender = Male</p>
<img src ="http://www.blogjava.net/michaelcao/aggbug/251183.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/michaelcao/" target="_blank">依然Fantasy</a> 2009-01-13 21:07 <a href="http://www.blogjava.net/michaelcao/archive/2009/01/13/251183.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>