Decode360's Blog

          業精于勤而荒于嬉 QQ:150355677 MSN:decode360@hotmail.com

            BlogJava :: 首頁 :: 新隨筆 :: 聯系 ::  :: 管理 ::
            302 隨筆 :: 26 文章 :: 82 評論 :: 0 Trackbacks

          一、Cursor的分類

          ?

          ?

          ?

          ?

          ?

          二、各類Cursor舉例

          ?

          ?

          ---- 靜態游標 - 顯式游標

          set serveroutput on

          declare

          ? cursor emp_sor(emp_deptno in number ) is

          ??? select * from emp where deptno=emp_deptno ;

          ? emp_i emp% rowtype ;

          begin

          ? dbms_output.put_line( 'Getting emp from deptno 10' );

          ? open emp_sor( 10 );

          ? loop

          ??? fetch emp_sor into emp_i;

          ??? exit when emp_sor% notfound ;

          ??? dbms_output.put_line( 'Employee id ' ||emp_i.empno|| ' is:' );

          ??? dbms_output.put_line(emp_i.ename);

          ? end loop ;

          ? close emp_sor;

          end ;

          /

          ?

          ?

          ---- 靜態游標 - 隱式游標 -1.DML

          begin

          ? update emp set ename=ename ; --where 1=2;

          ?dbms_output.put_line( 'update ' || sql % rowcount || ' records' );

          end ;

          /

          ?

          ---- 靜態游標 - 隱式游標 -2.loop for

          begin

          ? for r_sor in ( select empno,ename from emp)

          ? loop

          ?? dbms_output.put_line(r_sor.empno || ' : ' || r_sor.ename);

          ? end loop ;

          end ;

          /

          ?

          ---- 靜態游標 - 隱式游標 -3.select into

          declare

          ? v? varchar2 ( 20 );

          begin

          ? select ename into v from emp

          ? where rownum = 1 ;

          ? dbms_output.put_line(v);

          ? dbms_output.put_line( sql % rowcount );

          end ;

          /

          ?

          ?

          ?

          ---- 動態游標 - 弱類型

          Declare

          ? type rc is ref cursor ;

          ? cursor c is select * from dual;

          ? l_cursor rc;

          begin

          ? if (to_char( sysdate , 'dd' ) = 30 ) then

          ???? open l_cursor for 'select * from emp' ;-- ref cursor with dynamic sql

          ? elsif (to_char( sysdate , 'dd' ) = 29 ) then

          ???? open l_cursor for select * from dept;-- ref cursor with static sql

          ? else

          ???? open l_cursor for select * from dual;-- with ref cursor with static sql

          ? end if ;

          ? open c;-- the "normal" static cursor

          end ;

          /

          ?

          ?

          ---- 動態游標 - 強類型

          declare

          ? type emp_job is record (empno number ,

          ???????????????????????? ename varchar2 ( 20 ),

          ???????????????????????? job?? varchar2 ( 30 )

          ???????????????????????? );

          ? type emp_refcur is ref cursor return emp_job; -- 聲明 REF CURSOR

          ? emp_sor emp_refcur;

          ? emp_i?? emp_job;

          begin

          ? open emp_sor for

          ??? select empno,ename,job from emp where rownum < 10 order by 1 ;

          ? loop

          ??? fetch emp_sor into emp_i;

          ? exit when emp_sor% notfound ;

          ??? dbms_output.put_line(emp_i.ename || '''s job is :' );

          ??? dbms_output.put_line(emp_i.job);

          ? end loop ;

          ? close emp_sor;

          end ;

          /

          ?

          ?

          普通cursor與REF cursor的區別:

          1)靜態cursor不能返回到客戶端,只有PL/SQL才能利用它。ref cursor能夠被返回到客戶端,這就是從Oracle的存儲過程返回結果集的方式。

          2)靜態cursor可以是全局的,而ref cursor則不是。

          3)ref cursor可以從子例程傳遞到子例程,而cursor則不能。為了共享靜態cursor,必須在包說明或包體中把它定義為全局cursor。

          ?? 因為使用全局變量通常不是一種很好的編碼習慣,因此可以用ref cursor來共享PL/SQL中的cursor,無需混合使用全局變量。

          4)使用靜態cursor,通過靜態SQL(但不用ref cursor),比使用ref cursor效率高,而ref cursor的使用僅限于以下幾種情況:

          ????1.把結果集返回給客戶端;
          ????2.在多個子例程之間共享cursor(實際上與上面提到的一點非常類似);
          ????3.沒有其他有效的方法來達到你的目標時,則使用ref cursor,正如必須用動態SQL時那樣

          ?

          ?

          ?

          ---- 動態游標 -sys_refcursor

          DECLARE

          ? TYPE mytable IS TABLE OF emp% ROWTYPE ;

          ? l_data mytable;

          ? l_refc sys_refcursor ;

          BEGIN

          ? OPEN l_refc FOR

          ? SELECT empno,ename,job,mgr,hiredate,sal,comm,deptno FROM emp;

          ? FETCH l_refc BULK COLLECT INTO l_data;

          ? CLOSE l_refc;

          ? FOR i IN 1 .. l_data.COUNT

          ? LOOP

          ??? DBMS_OUTPUT.put_line ( l_data(i).ename || ' was hired since ' || l_data (i).hiredate );

          ? END LOOP ;

          END ;

          ?

          ?

          非強類型的Ref cursor 和sys_refcursor的區別:

          A REF CURSOR that does not specify the return type such as SYS_REFCURSOR. Meaning the SYS_REFCURSOR can be opened for a dynamic SQL query, where as simple REF CURSOR can not be opened for a query dynamically built at execution time.

          ?

          ?

          ?

          ?

          ?

          ?

          三、游標屬性

          ?

          ?

          /*************************************************************

          游標屬性:

          %FOUND :變量最后從游標中獲取記錄的時候,在結果集中找到了記錄。

          %NOTFOUND :變量最后從游標中獲取記錄的時候,在結果集中沒有找到記錄。

          %ROWCOUNT :當前時刻已經從游標中獲取的記錄數量。

          %ISOPEN :是否打開。

          **************************************************************/

          ?

          ---- 靜態游標 - 游標屬性

          Declare

          ? Cursor emp_sor is

          ? Select * from emp where rownum< 6 order by 1 ;

          ? emp_i emp% rowtype ;

          ? num number := 1 ;

          Begin

          ? Open emp_sor;

          ? Fetch emp_sor into emp_i;

          ? Loop

          ??? If emp_sor% found then

          ????? Dbms_output.put_line( 'Looping over record ' ||num|| ' of ' || emp_sor% rowcount );

          ????? Fetch emp_sor into emp_i;

          ? ???? num := num + 1 ;

          ??? Elsif emp_sor% notfound then

          ????? Exit ;? ---exit loop, not IF

          ??? End if ;

          ? End loop ;

          ?

          ? If emp_sor% isopen then

          ??? Close emp_sor;

          ? End if ;

          End ;

          /

          ?

          ?





          -The End-

          posted on 2008-08-29 17:43 decode360-3 閱讀(1675) 評論(0)  編輯  收藏 所屬分類: SQL Dev
          主站蜘蛛池模板: 新巴尔虎左旗| 綦江县| 沧源| 公主岭市| 甘德县| 罗江县| 浦北县| 龙口市| 定兴县| 哈密市| 黄山市| 于田县| 甘南县| 兴文县| 迁安市| 修武县| 旬邑县| 视频| 乌拉特后旗| 盐津县| 乌苏市| 汪清县| 新绛县| 双牌县| 云梦县| 磐安县| 津市市| 永顺县| 乌海市| 建水县| 福建省| 温泉县| 湖北省| 军事| 西畴县| 九江县| 佛坪县| 蒙阴县| 锦州市| 凤凰县| 疏勒县|