
逐行處理查詢結果,以編程的方式訪問數據
游標的類型:
1,隱式游標:在 PL/SQL 程序中執行DML SQL 語句時自動創建隱式游標,名字固定叫sql。
2,顯式游標:顯式游標用於處理返回多行的查詢。
3,REF 游標:REF 游標用於處理運行時才能確定的動態 SQL 查詢的結果
begin
update student s set s.sage = s.sage + 10 ;
if sql %FOUND then
dbms_output.put_line('這次更新了' || sql% rowcount );
else
dbms_output.put_line ('一行也沒有更新' );
end if;
end;
SQL> declare
2 sname1 student.sname%TYPE;
3 begin
4 select sname into sname1 from student;
5 if sql%found then
6 dbms_output.put_line(sql%rowcount);
7 else
8 dbms_output.put_line('沒有找到數據');
9 end if;
10 exception
11 when too_many_rows then
12 dbms_output.put_line('查找的行記錄多於1行');
13 when no_data_found then
14 dbms_output.put_line('未找到匹配的行');
15 end;
16 /
查找的行記錄多於1行
PL/SQL procedure successfully completed
SQL>

------------------------------------無參數游標-------------------------------
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;
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;