小游标

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了小游标相关的知识,希望对你有一定的参考价值。

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

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

    游标: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属于强类语句,变量声明是确定,一旦确定不可改变,弱类大体也就这回事。

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

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

以上是关于小游标的主要内容,如果未能解决你的问题,请参考以下文章

项目中使用Redis的游标scan的一些小问题

MySQL从入门到精通50讲(二十一)-CURSOR游标

MySQL从入门到精通50讲(二十一)-CURSOR游标

临时表和游标的使用小总结

SqlServer 利用游标批量更新数据

数据库小技能:PL/SQL中书写定义sql