oracle中的游标的原理和使用详解


游标

游标的简介:

逐行处理查询结果,以编程的方式访问数据

游标的类型:

1,隐式游标:在 PL/SQL 程序中执行DML SQL 语句时自动创建隐式游标,名字固定叫sql。

2,显式游标:显式游标用于处理返回多行的查询。

3,REF 游标:REF 游标用于处理运行时才能确定的动态 SQL 查询的结果

隐式游标:



q在PL/SQL中使用DML语句时自动创建隐式游标

q隐式游标自动声明、打开和关闭,其名为 SQL

q通过检查隐式游标的属性可以获得最近执行的DML 语句的信息

q隐式游标的属性有:

q%FOUND – SQL 语句影响了一行或多行时为 TRUE

q%NOTFOUND – SQL 语句没有影响任何行时为TRUE

q%ROWCOUNT – SQL 语句影响的行数

q%ISOPEN  - 游标是否打开,始终为FALSE


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;

在select中有两个中比较常见的异常:

1. NO_DATA_FOUND

2. TOO_MANY_ROWS


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> 

显式游标:



sqlserver与oracle的不同之处在于:

最后sqlserver会deallocate 丢弃游标,而oracle只有前面四步:

声明游标、打开游标、使用游标读取记录、关闭游标。

显式游标的使用:


------------------------------------无参数游标-------------------------------

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;

REF游标也叫动态游标:



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;

时间: 2024-10-26 02:01:59

oracle中的游标的原理和使用详解的相关文章

oracle中的exists 和not exists 用法详解

oracle中的exists 和not exists 用法详解 有两个简单例子,以说明 “exists”和“in”的效率问题 1) select * from T1 where exists(select 1 from T2 where T1.a=T2.a) ; T1数据量小而T2数据量非常大时,T1<<T2 时,1) 的查询效率高. 2) select * from T1 where T1.a in (select T2.a from T2) ; T1数据量非常大而T2数据量小时,T1>

oracle中的exists 和not exists 用法详解(转)

有两个简单例子,以说明 “exists”和“in”的效率问题 1) select * from T1 where exists(select 1 from T2 where T1.a=T2.a) ; T1数据量小而T2数据量非常大时,T1<<T2 时,1) 的查询效率高. 2) select * from T1 where T1.a in (select T2.a from T2) ; T1数据量非常大而T2数据量小时,T1>>T2 时,2) 的查询效率高. exists 用法:

oracle中去掉回车换行空格的方法详解

函数: 1.translate语法:TRANSLATE(char, from, to)用法:返回将出现在from中的每个字符替换为to中的相应字符以后的字符串.            若from比to字符串长,那么在from中比to中多出的字符将会被删除.            三个参数中有一个是空,返回值也将是空值. 举例:SQL> select translate('abcdefga','abc','wo') 返回值 from dual; 2.replace语法:REPLACE(char,

oracle中的游标(转)

Oracle中的游标有两种:显式游标.隐式游标.显示游标是用cursor...is命令定义的游标,它可以对查询语句(select)返回的多条记录进行处理,而隐式游标是在执行插入 (insert).删除(delete).修改(update)和返回单条记录的查询(select)语句时由PL /SQL 自动定义的. 显式游标 当声明了显式游标后,可以通过以下三条命令控制显式游标的操作:打开游标.推进游标.关闭游标. 声明显式游标 Ø  无参游标 cursor c_auths is select * f

Oracle中的游标(光标)--来自Oracle赵强老师

 表.select语句.游标:返回结果都能是一个集合. 注意:游标的结果是一个集合. --查询并打印员工的姓名和薪水 set serveroutput on /* 光标: 1. 光标的属性: %isopen %rowcount(返回的行数) %notfound %found 2. 默认情况下,一次性打开300个光标 SQL> show parameter cursor NAME TYPE VALUE ------------------------------------ ---------

Oracle中使用游标获取指定数据表的所有字段名对应的字符串

操作步骤:打开PLSQL Developer后,直接执行下面的语句就可以出来 --Oracle中使用游标获取指定数据表的所有字段名对应的字符串 declare mytablename VARCHAR(255):='STAFFDOC'; --定义要查询的数据表名变量,STAFFDOC为我测试用的数据表名,请修改成您的数据库中的对应数据表名字mystring NVARCHAR2(4000):=''; --定义要输出的字符串变量 cursor mycursor is --定义游标          s

Oracle中使用游标转换数据表中指定字段内容格式(拼音转数字)

应用场景:将数据表TB_USER中字段NNDP的内容中为[sannanyinv]转换为[3男1女] 主要脚本:一个游标脚本+分割字符串函数+拼音转数字脚本 操作步骤如下: 1.创建类型 create or replace type splitTable is table of varchar2(100); 2.创建函数fn_splitString(功能是将字符串分割成多条记录)--测试语句select * from table(fn_splitString('ernanyinv','nan'))

Oracle 中的游标(用Javase中Iterator 类比之)

当使用 pl/sql 查询 Oracle 数据库时,有时我们想输出多条记录的数据.:select * from scott.emp; 这时,我们一定会想利用循环来输出.但是,在pl/sql 中是没有数组类型的,那么用什么来暂时保存查询出来的结果集那? 这时.就要使用 cursor(游标). 1.定义游标: 2.打开游标: 3.查询数据: 4.关闭游标: 5.提交事务: 6.错误处理: Oracle 中的游标(用Javase中Iterator 类比之)

ios中创建可以拖动的view原理和实现详解

有时候我们会需要在界面上拖动view;uiview是继承于uiresponder的,所以可以响应触摸相关的事件. 重点是以下一组方法: - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event - (void)touchesEnded:(NSSet *)touches withEvent:(UIE