查看: 1979|回复: 0

[Oracle数据库] 小游标

发表于 2018-1-28 10:07:38

游标听名字就很奇特,仿佛水中的鱼在大海中游来游去。

数据库中什么叫游标,有啥好处,干啥用下面来说说

游标:Oracle本质是数据库,那么也应该提供方便访问数据的方法,游标的本质允许用户针对某个结果集进行逐行访问。类似于编程中的指针,可以进行位置的移动,以循环访问结果集中的每条记录。通过游标可以访问当前记录。

我们先来分享游标属性

游标属性是针对游标的状态,反映当前有标的状态

1、found属性用于标识当前游标从结果中获取记录时,是否能获取到纪录,放回的是布尔值基于判断。

2、nofound属性属性对立,如果获取不到则返true。

3、rowcount属性用于返回当前获得多少条记录。

4、isopen用于判断游标当前的状态,是否打开。该属性被游标OPEN,CLOSE动作更新。

显示游标:

显示游标如同声明变量一样,遵循以下几个步骤,声明打开访问关闭。

格式:

declare cursor cu_student is select * from student;--将游标cu_student指向结果集

students student%rowtype;--声明变量用于存储游标中记录

解释:

关键字declaer cursor来声明一个游标,is后面指定是对标进行操作查询的结果集,%rowtype是指定原表中类型要和结果集中查询列的数据类型对应,单行指定可以是%type来获取,如果对表结构清晰,每一列的类型把握可以直接后面跟类型指定。

格式:

delare cursor cu_student (max in number,min in number) is select % from student;

where student_age>=min and student_age<=max

students student%rowtype;

解释:

我们还记着存储过程中IN参数使用,这里的IN仍然是输入,传递两个参数,二者类型是number。

声明了怎样使用呢?

格式:

set serveroutput on;--开启输出

----------------------------------------------------------------------------------------------------------------------

格式:

declare cursor cu_sudent is select student_id,student_name from students;

student_id student.student_id%type;

student_name student.student_name%type;

begin

open cu_sudent;--打开游标

fetch cu_sudent into sudent_id,sudent_name;

while cu_sudent%found loop

dbms_output.put_line(student_id || '-' || student_name);

fetch cu_student into student_id,student_name;

end loop;

close cu_sudent;--关闭游标

end;

----------------------------------------------------------------------------------------------------------------------

解释:

上面注释已经对部分代码进行了注释,在声明游标之后并不意味着游标真正的打开,只是游标状态处于可用,在OPEN之后才算游标正常使用,后面通过游标属性测试来证实。一定要关闭游标,因为游标在内存中,若果大量的游标没有关闭后果比较严重。

----------------------------------------------------------------------------------------------------------------------

带参数的显示游标:

比如我们有一个需求,输入男女就可以打印班级中男生或女生同学的信息

declare cursor cu_student (input_sex in varchar2(2)) is select * from student

where student_sex = input_sex;

students student%rowtype;

begin

open cu_student(&user_date);--提示让你输入

fetch cu_student into students;

while cu_student%found loop

dbms_output.put_line(students.student_name || '-' || students_student_age || '-' || studenst_student_sex);

fetch cu_student into students;

end loop;

close cu_student;

end;

----------------------------------------------------------------------------------------------------------------------

隐式游标;

其实隐式更应该值得我们关注,那么显示更符合我们的逻辑思维,有我们能把控的生命周期,从生命到关闭游标,隐式则不需要声明打开关闭步骤,不能直接被用户控制和使用。两种1、SQL隐式游标

----------------------------------------------------------------------------------------------------------------------

格式:

begin

if sql%rowcount > 0 then--获取记录

dbms_output.put_line('sql游标变量rowcount属性大于0');

else

dbms_output.put_line('游标存在,但是没有记录');

end if;

end;

----------------------------------------------------------------------------------------------------------------------

解释:

来测试游标的行数,根据判断判断条件来抓取记录.注意每次使用DML时候,Oracle自动更新该变量,SQL变量是被Oracle自动声明的,不被用户控制的特点。

游标sql并不能使用fetch命令进行显示操作,那么用于更新、删除等操作之后的属性信息获取。

Cursor for游标

sql游标可以应用于更新删除数据等操作,为了能处理select语句获得的结果集,利用该游标可以像显示一样循环处理结果集获得每一条记录。

----------------------------------------------------------------------------------------------------------------------


格式:

begin

for student in (select * from students) loop

dbms_output.put_line(student.student_id|| '-'........);

end loop;

end;

----------------------------------------------------------------------------------------------------------------------

解释:

那么本次代码利用for循环来,如for(int i;i<=1000;i++)中的i一样.

显示隐式好处我们在代码中逐步的展示和对比,显示我们能更灵活的控制游标的生命周期,逻辑思维也很清晰,那么隐式相对来说代码量较少,而且省略了声明等操作,隐式sql配合cursor for能实现显示的功能,隐式的游标处理速度相对来说更快!所以在对显示要求不高的情况下,应该对隐式游标进行使用。

动态游标

无论是显示还是隐式,那么我们在打开游标那一刻,具有封闭性,定义已经确定,整个程序运行的过程中,不受其他因素的干扰,游标的定义不可更改。因此也被称作为静态游标。

为了增强游标的灵活性,在游标打开之后仍然可以定义动态修改。

两类:1、强类型动态游标 2、弱类型动态游标

一、强类型动态游标:

强类型是指声明时候游标声明的时候虽然没有定义其查询,但是已经指定了游标的返回类型。返回类型可以使Oracle内置类型,也可以是自定义的。

先自定义ref cursor游标类型,利用该类型声明一个游标变量。

----------------------------------------------------------------------------------------------------------------------

格式:

create or replace proceduer print(int_age in number) as --创建一个过程

begin

declare student_type is record(id number,age number);--声明student_type自动以类型,该类型基类是record包含了两个属性id,age。

type students_type is ref cursor return student_type;--ref cursor声明是一个动态的,返回结果集类型是student_type(游标类型),必须先声明结果集类型,在声明游标类型不可颠倒。

students students_type;--声明游标类型

student student_type;--声明结果集类型

begin

if in_age <= 0 then

open students for select * from students;--当传入为0的时候当打开游标获得表students所有记录。

else

open students for select * from students where student_age = in_age;--传入大于0的时候,安好输入信息查询。

end if;

fetch students into student;--获取游标中的记录,并存储变量中student

while student%found loop--用循环来输出学生信息

dbms_output.put_line

fetch students into students;

end loop;

close students;

end;

end print;

----------------------------------------------------------------------------------------------------------------------

格式:

begin

print(-1);

end;

解释:调用方式

----------------------------------------------------------------------------------------------------------------------

弱类型动态游标

比如说VB,JavaScript为弱类型,java,C属于强类语句,变量声明是确定,一旦确定不可改变,弱类大体也就这回事。

本章节不对弱类型做解释,因为本身学习也不是贴别好不误人子弟。

整合一下动态的两种游标,强类型动态游标在使用时候,必须声明其类型,在使用过程中,虽然定义可以修改,但是返回值是一定的。弱类型无须声明返回值类型,但在使用过程中,必须保证每次用于获取记录类型能够正确的接收来自游标的数据,因此也存在一定风险,尽量避免使用。



回复

使用道具 举报