数据库游标学习记录

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/ITdevil/article/details/81118204

一、游标的定义:游标是一个容器,用来记录查询结果集的,本质是一块内存,如果不释放,就会占用内存,这就是为什么open之后还要close操作。

二、游标的优缺点:

1.优点:游标的一个常见用途就是保存查询结果,以便以后使用。游标的结果集是由SELECT语句产生,如果处理过程需要重复使用一个记录集,那么创建一次游标而重复使用若干次,比重复查询数据库要快的多;如果我们要对查询出的结果做特殊处理,然后在进行下一步操作(比如将数据存新表),使用游标也是比较方便的;

2.缺点:当数据量非常大时,使用游标会带来很大的效率问题,因为游标其实是相当于把磁盘数据整体放入了内存中,游标数据量大的话则会造成内存不足;另外系统上跑的不只是一个业务,游标使用会对行加锁,可能影响其他业务的正常进行。所以慎用游标

三、游标的具体使用:

1.显示游标

显示游标的属性,通常用来获取一个游标的状态信息

1.1、isopen(Boolean):如果游标是打开的,那么这个游标的值为true

1.2、notfound(Boolean):如果最近一次的fetch操作没有返回一行数据,那么此值为true

1.3、found(Boolean):如果最近一次的fetch操作返回一行数据,那么此值为true

1.4、rowcount(Number):返回行数的总和,使用时的格式:”游标名%rowcount“,注意不能在游标打开之前和游标关闭之后使用此属性。

显示游标的使用步骤:

a.定义游标

b.打开游标

c.提取游标数据

d.关闭游标

具体使用:(从两张表中按照一些规定抽出部分数据)

declare
  orgVar       varchar2(30);
  psuhDateVar  varchar2(30);
  memLevelVar  varchar2(30);
  lowVar       varchar2(30);
  validVar     varchar2(30);
  effectiveVar varchar2(30);
  cursor OrgAndExpireData is
    select a.config_org,
           a.push_date,
           case a.mem_level
             when '0' then
              '1,2,3,4,5,6'
             else
              a.mem_level
           end mem_level,
           a.lowest_source_expire,
           a.is_valid,
           a.effective_date
      from integral_expire_rules a
      left join push_date_table b
        on a.config_org = b.config_org
     where a.is_valid = '1'
       and to_char(a.effective_date, 'yyyy-MM-dd') <=
           to_char(sysdate, 'yyyy-MM-dd')
       and a.push_date = to_char(sysdate, 'dd');
  -- and (to_char(b.push_finish_date,'yyyy-MM')!=to_char(sysdate,'yyyy-MM') or b.push_finish_date is null);

begin
  open OrgAndExpireData;
  loop
    fetch OrgAndExpireData
      into orgVar, psuhDateVar, memLevelVar, lowVar, validVar, effectiveVar;
    exit when OrgAndExpireData%notfound;
    dbms_output.put_line(orgVar || '.....' || psuhDateVar);
  end loop;
  close OrgAndExpireData;
end;

2、隐式游标

使用隐式游标时,不需要我们手动执行open,fetch,close操作了,PL/SQL语言提供了游标FOR循环语句,自动执行游标的OPEN、FETCH、CLOSE语句和循环语句的功能;

隐式游标是不需要定义的,系统默认等同为游标的,入一个select语句,DML语句,都会打开一个游标。

2.1.当进入循环时,游标For循环语句自动打开游标,并提取第一行游标数据;

2.2.当程序处理完当前所提取的数据而进入下一次循环时,游标FOR循环语句自动提取下一行数据供程序处理;

2.3.当程序处理完当前所提取的数据而进入下一次循环时,游标for循环语句自动提取下一行数据供程序处理;

declare

cursor OrgAndExpireData is
       select *           
       from integral_expire_rules a left join push_date_table  b
       on a.config_org=b.config_org
       where a.is_valid='1'
       and to_char(a.effective_date,'yyyy-MM-dd')<=to_char(sysdate,'yyyy-MM-dd')
       and a.push_date=to_char(sysdate,'dd');
      -- and (to_char(b.push_finish_date,'yyyy-MM')!=to_char(sysdate,'yyyy-MM') or b.push_finish_date is null);
            
begin
   for storeVar in OrgAndExpireData loop
		 dbms_output.put_line(storeVar.rule_name||'....'||storeVar.mem_level||'..'||storeVar.is_valid);
		 end loop;
end;

参考博客:

https://www.zhihu.com/question/19777435/answer/37060426
https://blog.csdn.net/haiross/article/details/42967213

补充存储过程相关:

1.select into form  和 insert into select 的区别

1.1  insert into select
   语句形式为:Insert into Table2(field1,field2,...) select value1,value2,... from Table1
   或者:Insert into Table2 select  *  from Table1
   
   @1要求目标表Table2必须存在,并且字段field,field2...也必须存在
   @2注意语法,不要加values,和插入一条数据的sql混了,不要写成:
           Insert into Table2(field1,field2,...) values (select value1,value2,... from Table1)
           
1.2 select into form
    语句形式为:SELECT vale1, value2 into Table2 from Table1
    要求目标表Table2不存在,因为在插入时会自动创建表Table2,并将Table1中指定字段数据复制到Table2中
             
2.存储过程中不能直接使用ddl语句,如truncate table,需要这种形式:
    execute immediate 'truncate table emp';注意,引号内不能加分号

猜你喜欢

转载自blog.csdn.net/ITdevil/article/details/81118204
今日推荐