游标

发布时间 2023-07-13 10:16:50作者: WeChat2834
游标

游标是sql的一个内存工作区,由系统或用户以变量的形式定义。游标的作用就是用于临时存储从数据库中提取的数据块。在某些情况下,需要把数据从存放在磁盘的表中调到计算机内存中进行处理,最后将处理结果显示出来或者最终写回数据库。这样数据处理的速度才会提高,否则频繁的磁盘数据交换会降低效率。

隐式游标

如前所诉,DML操作和单行SELECT 语句会使用隐式游标,

  • 插入操作 insert

  • 更新操作 update

  • 删除操作 delete.

  • 单行查询操作 select .... into ....

当系统使用一个隐式游标时,可以通过隐式游标的属性来了解操作的状态和结果,进而控制程序的流程。隐式游标可以使用名字sql来访问,但要注意,通过sql游标名总是只能访问前一个DML操作或单行select操作的游标属性,所以通常在刚刚执行完操作只会,立即使用sql游标名来访问属性。

隐式游标属性

隐式游标属性返回值类型意义
sql%rowcount 整数 代表DML语句执行的数据行数
sql%found 布尔型 值为true代表插入,删除,或更新或单行查询操作成功
sql%notfound 布尔型 与sql%found 属性返回值相反
sql%isopen 布尔型 DML执行过程中为真,结束后为假

 

显示游标
游标的使用分以下4个步骤
  1. 声明游标

    在declare部分进行声明

    CURSOR [游标名(参数1 数据类型[,参数2 数据类型...])]
    is  select 语句;

    参数是可选部分,所定义的参数可以出现在select 语句的where子句中。如果定义了参数,则必须在打开游标时传递相应的实际参数。

  2. 打开游标

    在可执行部分,按以下格式打开游标。

    open 游标名[参数1[,参数2...]];

    打开游标时,select语句的查询结果就被传送到了游标工作区

  3. 提取数据

    在可执行部分,按以下格式将游标工作区中的数据提取到变量中,提取操作必须在打开游标之后进行。

    fetch 游标名 into 变量名1[,变量名2...];

    fetch 游标名 into 记录变量名;

    游标打开后有一个指针指向数据区,fetch语句一次返回指针所指的一行数据,要返回多行需重复执行,可以使用循环语句来实现。

    ---游标使用举例
    ---eg1使用普通变量
    declare
      cursor cur_my
       is select 金额  from xujb_temp_hz2 b where b.blnc_id='2830000133';
      kpi number;  -----普通变量
    begin
      open cur_my ;
          fetch cur_my into kpi;
          dbms_output.put_line('该blnc2830000133金额为'||kpi);
      close cur_my;
    end;

    ---游标使用举例
    ---eg2使用记录变量
    declare
      cursor cur_my
       is select *  from xujb_temp_hz2 b  where b.blnc_id='2830000133';
      blnckpi xujb_temp_hz2%rowtype;  -----xujb_temp_hz2表的记录变量
    begin
      open cur_my ;
          fetch cur_my into blnckpi;
          dbms_output.put_line('该blnc'||blnckpi.blnc_id||'金额为'||blnckpi.金额);
      close cur_my;
    end;
    ---游标使用举例
    ---eg3使用游标变量
    declare
      cursor cur_my
       is select *  from xujb_temp_hz2 b  where b.blnc_id='2830000133';
      blnckpi cur_my%rowtype;  -----游标变量
    begin
      open cur_my ;
          fetch cur_my into blnckpi;
          dbms_output.put_line('该blnc'||blnckpi.blnc_id||'金额为'||blnckpi.金额);
      close cur_my;
    end;

     

  4. 关闭游标

    显示游标打开后,必须显示的关闭。游标一旦关闭,游标占用的资源就被释放,游标变成无效,必须重新打开才能使用。

    close 游标名;

    显示游标属性

显示游标属性返回值类型意义
%rowcount 整数 代表DML语句执行的数据行数
%found 布尔型 值为true代表插入,删除,或更新或单行查询操作成功
%notfound 布尔型 与sql%found 属性返回值相反()
%isopen 布尔型 DML执行过程中为真,结束后为假s
---游标循环遍历举例1
---eg4循环打印游标所有数据
declare
  cursor cur_my
   is select *  from xujb_temp_hz2 b ;
  blnckpi cur_my%rowtype;  -----游标变量
begin
  open cur_my ;
      loop
          fetch cur_my into blnckpi;---循环取数传入变量
        exit when cur_my%notfound;  ----游标数据取完后退出循环
        dbms_output.put_line('该blnc'||blnckpi.blnc_id||'金额为'||blnckpi.金额);
        end loop;
  close cur_my;
end;



---游标循环遍历举例2
---eg5循环打印游标所有数据,使用for循环
declare
  cursor cur_my
   is select *  from xujb_temp_hz2 b ;
begin
      for i_cur in cursor loop    -----i_cur就是游标变量
          dbms_output.put_line('该blnc'||i_cur.blnc_id||'金额为'||i_cur.金额);
      end loop;
end;
---游标循环遍历举例3
---eg6循环打印游标所有数据,使用for循环更简单方式,游标都不用定义
declare  
begin
      for i_cur in (select *  from xujb_temp_hz2) loop    -----i_cur就是游标变量,
          dbms_output.put_line('该blnc'||i_cur.blnc_id||'金额为'||i_cur.金额);
      end loop;
end;
游标参数 的传递

 

---游标循环遍历举例1 传递参数
---eg7循环打印游标所有数据
declare
  cursor cur_my(blnc_ids varchar2,vtypess xujb_temp_hz2.类别%type)----注意,此处的类型varchar2这类不能加长度(例如eg varchar2(20)这么写)
   is select b.blnc_name,b.金额  from xujb_temp_hz2 b  where b.blnc_id=blnc_ids and b.类别=vtypess ;
  blnckpi cur_my%rowtype;  -----游标变量
begin
  open cur_my('31000239','规则') ;
      loop
          fetch cur_my into blnckpi;---循环取数传入变量
        exit when cur_my%notfound;  ----游标数据取完后退出循环
        dbms_output.put_line('该blnc'||blnckpi.blnc_id||'金额为'||blnckpi.金额);
        end loop;
  close cur_my;
end;

---游标循环遍历举例2 用变量传递参数
---eg7循环打印游标所有数据
declare
  blnc_ids varchar2(20):='31000239';
  vtypess xujb_temp_hz2.类别%type:='规则';
  cursor cur_my
   is select b.blnc_name,b.金额  from xujb_temp_hz2 b  where b.blnc_id=blnc_ids and b.类别=vtypess ;
  blnckpi cur_my%rowtype;  -----游标变量
begin
  open cur_my;
      loop
          fetch cur_my into blnckpi;---循环取数传入变量
        exit when cur_my%notfound;  ----游标数据取完后退出循环
        dbms_output.put_line('该blnc'||blnckpi.blnc_id||'金额为'||blnckpi.金额);
        end loop;
  close cur_my;
end;

 

动态select语句和动态游标的用法

oracel支持动态select 语句和动态游标,动态的方法大大扩展了程序的设计能力。

  • 动态select语句对于查询结果为一行的select语句,可以用动态生成查询语句字符串的方法,在程序执行阶段临时的生成并执行,语法

declare
  sql2 varchar2(2000);
  sql3 varchar2(2000);
  v_blncname xujb_temp_hz2.blnc_name%type;
  v_金额     xujb_temp_hz2.金额%type;
begin
  sql2:='select blnc_name,金额 from xujb_temp_hz2 b where b.blnc_id=''2830021''';
  sql3:='select blnc_name,金额 from xujb_temp_hz2 b where b.blnc_id=''2830027''';
  execute immediate sql2 into v_blncname,v_金额;-- execute immediate强制立即执行
  dbms_output.put_line('该blnc'||v_blncname||'金额为:'||v_金额);
end;

 

execute immediate  查询语句字符串  into  变量1[,变量2...];
  • 动态游标,自己定义的游标类型,sql语句返回多条数据

    1. 定义游标类型 语法如下

      type 游标类型名 is ref cusor;

       

    2. 声明游标变量的语法如下

      游标变量名 游标类型名;

       

    3. 在可执行部分如下形式打开一个动态游标

      open  游标变量名 for 查询语句字符串;
      --eg1 动态游标举例
      declare
      type curblnc is ref cursor; --自定义游标类型
      cur_my curblnc;  --自定义游标类型变量
      v_list xujb_temp_hz2%rowtype;----这不能直接使用游标变量,只能使用表记录变量,应该是语句未先定义的缘故
      str varchar2(2000);
      v_类别 xujb_temp_hz2.类别%type default '发放规则'; ---该参数可以用于字符串的拼接连接条件
      begin
      str:='select * from xujb_temp_hz2 b where b.类别='''||v_类别||'''';
          open cur_my for str;
              loop
                  fetche cur_my into v_list;
              exit when cur_my%notfound;
                  dbms_out.put_line('blnc名:'||v_list。blnc_name||'金额为'||v_list.金额);
              end loop;
          close cur_my;
      end;

       

    4.