Oracle中的遊標的原理和使用詳解
阿新 • • 發佈:2019-02-06
REF遊標也叫動態遊標:declare sname varchar2( 20); --宣告變數 cursor student_cursor is select sname from student ; --宣告遊標 begin open student_cursor; --開啟遊標 fetch student_cursor into sname; --讓遊標指標往下移動 while student_cursor%found --判斷遊標指標是否指向某行記錄 loop --遍歷 dbms_output.put_line ('學生姓名' ||sname ); fetch student_cursor into sname; end loop; close student_cursor; end; ------------------------------------有引數遊標------------------------------- declare sname student.sname%type; sno student.sno%type; cursor student_cursor (input_sno number) is select s.sname, s.sno from student s where s.sno > input_sno; --宣告帶引數的遊標 begin sno := &請輸入學號; --要求從客戶端輸入引數值,"&"相當於佔位符; open student_cursor( sno); --開啟遊標,並且傳遞引數 fetch student_cursor into sname, sno; --移動遊標 while student_cursor% found loop dbms_output.put_line ('學號為:' ||sno ||'姓名為:' ||sname ); fetch student_cursor into sname,sno; end loop; close student_cursor; end; ------------------------------------循環遊標------------------------------- -- Created on 18-1月-15 by 永文 declare stu1 student%rowtype ; --這裡也不需要定義變數來接收fetch到的值 cursor student_cursor is select * from student ; begin open student_cursor; --這裡不需要開啟遊標 for stu1 in student_cursor loop dbms_output.put_line ('學生學號:' ||stu1.sno ||'學生姓名:' ||stu1.sname ); fetch student_cursor into stu1; --也不需要fetch了 end loop; close student_cursor; --這裡也不需要關閉遊標 end; ------------------------------------使用遊標更新行------------------------------- declare stu1 student%rowtype ; cursor student_cursor is select * from student s where s.sno in (2 ,3 ) for update;--建立更新遊標 begin open student_cursor; fetch student_cursor into stu1;--移動遊標 while student_cursor%found --遍歷遊標,判斷是否指向某個值 loop update student set sage = sage + 10 where current of student_cursor;--通過遊標中的資訊更新資料 fetch student_cursor into stu1;--移動遊標 end loop; close student_cursor; end; declare stu1 student%rowtype ; cursor student_cursor is select * from student s where s.sno in (2 ,3 ) for update;--建立更新遊標 begin open student_cursor; -- fetch student_cursor into stu1;--移動遊標 -- while student_cursor%found--遍歷遊標,判斷是否指向某個值 loop fetch student_cursor into stu1 ;--移動遊標 exit when student_cursor %notfound ; update student set sage = sage + 10 where current of student_cursor;--通過遊標中的資訊更新資料 end loop; close student_cursor; end; ------------------------------------使用fetch ... bulk collect into------------------------------- declare cursor my_cursor is select ename from emp where deptno= 10; --宣告遊標 type ename_table_type is table of varchar2 (10 );--定義一種表型別,表中的屬性列為varchar2型別 ename_table ename_table_type;--通過上面定義的型別來定義變數 begin open my_cursor; --開啟遊標 fetch my_cursor bulk collect into ename_table; --移動遊標 for i in 1 ..ename_table.count loop dbms_output.put_line(ename_table(i)); end loop ; close my_cursor; end; -----------------------------------顯示遊標題目-------------------------------------- SQL > select * from student ; XH XM ---------- ---------- 1 A 2 B 3 C 4 D SQL > select * from address ; XH ZZ ---------- ---------- 2 鄭州 1 開封 3 洛陽 4 新鄉 完成的任務 :給表student新增一列zz ,是varchar2 (10 )型別; 再從address中,將zz欄位的數值取出來,對應的插入到 student新增的zz列中。 即:得到的結果:student表中,是: XH XM ZZ -- ---------- ------ 1 A 開封 2 B 鄭州 3 C 洛陽 4 D 新鄉 declare stu1 student %rowtype ; add1 address %rowtype ; cursor student_cursor is select * from student for update; --宣告更新遊標 cursor address_cursor is select * from address ; --宣告遊標 begin open student_cursor ; --開啟遊標 fetch student_cursor into stu1; --移動遊標 while student_cursor% found--判斷遊標是否指向某條記錄 loop open address_cursor ; --開啟另外一個遊標 fetch address_cursor into add1 ; --移動遊標 while address_cursor %found--判斷遊標是否指向某條記錄 loop if add1.xh = stu1.xh then--判斷兩個遊標所指向的記錄中xh的值是否相等 update student s set s.zz = add1.zz where current of student_cursor; --假如相等就更新遊標所指向的記錄值 end if; fetch address_cursor into add1 ; --移動遊標 end loop; close address_cursor ; --關閉遊標 fetch student_cursor into stu1 ; --移動遊標 end loop; close student_cursor ; --關閉遊標 end;
qREF 遊標和遊標變數用於處理執行時動態執行的 SQL 查詢 q建立遊標變數需要兩個步驟: q宣告 REF 遊標型別 q宣告 REF 遊標型別的變數 q用於宣告 REF 遊標型別的語法為:
TYPE <ref_cursor_name> IS REF CURSOR
[RETURN <return_type>];
-----------------------------------ref遊標--------------------------------- declare type ref_cursor is ref cursor; --宣告一個ref遊標型別 tab_cursor ref_cursor ;--宣告一個ref遊標 sname student.xm %type ; sno student.xh %type ; tab_name varchar2 (20 ); begin tab_name := '&tab_name'; --接收客戶輸入的表明 if tab_name = 'student' then open tab_cursor for select xh ,xm from student ; --開啟ref遊標 fetch tab_cursor into sno ,sname ;--移動遊標 while tab_cursor %found loop dbms_output.put_line ('學號:' ||sno ||'姓名:' ||sname ); fetch tab_cursor into sno ,sname ; end loop; close tab_cursor ; else dbms_output.put_line ('沒有找到你想要找的表資料資訊' ); end if; end; -----------------------------------ref遊標題目--------------------------------- SQL > select * from student ; XH KC ---------- ---------- 1 語文 1 數學 1 英語 1 歷史 2 語文 2 數學 2 英語 3 語文 3 英語 9 rows selected SQL > 完成的任務 : 生成student2表 (xh number, kc varchar2 (50 )); 對應於每一個學生,求出他的總的選課記錄,把每個學生的選課記錄插入到student2表中。 即,student2中的結果如下: XH KC --- ------------------------------------------- 1 語文數學英語歷史 2 語文數學英語 3 語文英語 create table student2 (xh number, kc varchar2 (50 )); declare kcs varchar2 (50 ); kc varchar2 (50 ); type ref_cursor is ref cursor; --宣告一個ref遊標型別 stu_cursor ref_cursor ;--定義一個ref遊標型別的變數 type tab_type is table of number; --宣告一個table型別 tab_xh tab_type ;--定義一個表型別的變數 cursor cursor_xh is select distinct( xh) from student; --宣告一個遊標 begin open cursor_xh; --開啟遊標 fetch cursor_xh bulk collect into tab_xh; --提取資料到表中 for i in 1 .. tab_xh.count loop kcs :='' ; open stu_cursor for select kc from student s where s.xh = tab_xh(i ); --開啟ref遊標 fetch stu_cursor into kc ; --移動遊標 while stu_cursor %found loop kcs := kc ||kcs ; --連線字串使用||而不是+ fetch stu_cursor into kc ; --移動遊標 end loop; insert into student2 (xh , kc ) values( i, kcs); close stu_cursor ; end loop; close cursor_xh ; end;