oracle中的游标的原理和使用详解
游标
逐行处理查询结果,以编程的方式访问数据
游标的类型:
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;
|
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。