`
kevin.wang
  • 浏览: 251188 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

显式-隐式游标

阅读更多
DECLARE   
t_a VARCHAR2(50);   
CURSOR cur_b(t_c VARCHAR2)IS SELECT d4.d401_02 FROM d401 d4 WHERE d4.d401_01 = t_c ;   
BEGIN   
OPEN cur_b('410126197904190319');   
  LOOP   
       FETCH cur_b INTO t_a ;   
       EXIT WHEN cur_b%NOTFOUND;   
            dbms_output.put_line(t_a);   
  END LOOP;   
CLOSE  cur_b ;   
END;  

游标的打开和关闭必须在循环的外边方可!

游标
环境区域是用来处理SQL语句的一个oracle存储区域。游标是指向它的指针或句柄。通过游标,PL/SQL程序可以控制这个环境区域中被处理的语句。
Oracle中的游标有两种:显式游标、隐式游标。
显示游标是用cursor...is命令定义的游标,它可以对查询语句(select)返回的多条记录进行处理,而隐式游标是在执行插入(insert)、删除(delete)、修改(update)和返回单条记录的查询(select)语句时由PL/SQL自动定义的。

1、显式游标操作
显式游标在块定义部分、包或子程序中声明。当声明了显式游标后,可以通过以下三条命令控制显式游标的操作:打开游标、推进游标、关闭游标。
(1)声明显式游标
--例1

declare   
  v_auths auths%rowtype;   
  v_code auths.author_code%type;   
  cursor c_auths is    
    select * from auths where author_code=v_code;  

上例是将PL/SQL变量绑定在WHERE子句中,下面将游标参数绑定在游标的WHERE子句中:
--例2
delcare   
  cursor c_auths(p_code auths.author_code%type) is   
    select * from auths where author_code=p_code;  
 


(2)打开显式游标
游标操作的第一步是打开游标。
例1,下面的语句是打开上节例1中声明的显式游标c_auths;

begin   
  --在打开游标前为绑定变量赋值。   
  v_code:='A00001';   
  --打开游标。   
  open c_auths;  


例2,如果对于一个带参数的游标

begin     
  --打开游标时将参数传入。     
  open c_auths('A00001');   

打开一个已打开的游标也是合法的。当第二次打开游标时,PL/SQL先自动关闭游标,然后再打开。一次打开多个游标也是PL/SQL所允许的。
(3)推进显式游标
当打开显式游标后,就可以使用FETCH语句来推进游标,返回查询结果集中的一行。每执行完一条FETCH语句后,显式游标会自动指向查询结果集的下一行。
  (4)关闭显式游标 (循环结束)
当整个结果集都检索完以后,应当关闭游标。关闭游标用来通知PL/SQL游标操作已经结束,并且释放游标所占用的资源(结果集所使用的资源空间)。

2、游标的属性
游标有四个属性:%found、%notfound、%isopen和%rowcount。要注意这些属性只能使用在过程性语句中,而不能使用在SQL语句中。
表tableattribute,表中有两列column1(number类型)和column2(varchar2类型),现在向表中插入两条记录:
insert into tableattribute values(10,'first');
insert into tableattribute values(20,'second');
...

3、显式游标的推进循环
delcare
  --声明一个变量,这个变量用来接收游标返回的结果集。
  v_salary auths.salary%type;
  v_code auths.author_code%type;
  /*声明游标,该游标的查询结果集是作家代码为"A00001"到"A00006"的工资值。*/
  cursor c_salary is select salary,author_code from auths where author_code<='A00006';
begin
  --打开游标,并初始化结果集
  open c_salary;
  loop
    --推进游标,将游标的查询结果集中的一行存到变量v_salary中。
    fetch c_salary into v_salary,v_code;
    --当结果集中没有行时退出循环。
    exit when c_salary%notfound;
    --如果查询到的作家工资小于或等于200,则增加该作家的工资值。
    if v_salary<=200 then
      update auths set salary=salary+50 where author_code=v_code;
    end if;
  end loop;
  --关闭游标,释放游标占用资源。
  close c_salary;
  --提交所做的修改。
  commit;
end; 



PL/SQL还提供了一种简单类型的循环,可以自动控制游标的打开、推进和关闭,叫做游标的FOR循环。

delcare   
  cursor c_salary is   
    select salary form auths where author_code<='A00006';   
begin   
  --开始游标FOR循环,隐含地打开c_salary游标。   
  for v_salary in c_salary loop   
    --一个隐含的fetch语句在这里被执行。   
  if v_salary.salary<=200 then   
      update auths set salary=salary+50 where salary=v_salary.salary;   
    end if;   
    --在循环继续前,一个隐含的c_auths%notfound被检测。   
 end loop;   
  --现在循环已经结束,c_auths游标的一个隐含的close操作被执行。   
  commit;   
end; 



使用current of cursor子句作为条件
delcare
  --声明游标时在select语句中必须加for update of子句。
  cursor c_salary is
    select salary form auths where author_code<'A00006' for update of salary;
begin
  for v_salary in c_salary loop
    if v_salary.salary<=200 then
      --下面的update语句中的current of子句用来表明结果集的当前行。
    end if;
  end loop;
  commit;
end; 

如果在游标的FOR循环中使用子查询,则不用在块定义部分声明显式游标,在FOR循环中子查询隐含声明了一个显式游标。


begin   
  --在下面的FOR循环中隐含地声明了一个游标c_salary。   
 for c_salary in   
  (select salary form auths where author_code<='A00006') loop   
    if c_salary.salary<=200 then   
      update auths set salary=salary+50 where salary=c_salary.salary;   
    end if;   
  end loop;   
  commit;   
end;  



4、隐式游标处理
PL/SQL隐式地打开SQL游标,并在它内部处理SQL语句,然后关闭它。SQL游标用来处理insert、update、delete以及返回一行的select...into语句。
一个SQL游标不管是打开还是关闭,open、fetch和close命令都不能操作它。SQL游标与显式游标类似,也有四个一样的属性。当打开SQL游标之前,SQL游标的属性都为NULL。


begin   
  update auths set entry_date_time=sysdate where author_code='A00017';   
  --如果update语句中修改的行不存在(SQL%notfound返回值为true),则向auths表中插入一行。   
  if sql%nofound then   
    insert into auths(author_code,name,sex,birthdate,salary,entry_date_time)   
      values('A000017','qiuys',1,'30-apr-40',88.5,sysdate);   
  end if;   
end; 


--如果update语句中修改的行不存在(sql%rowcount=0)
declare   
  v_birthdate date;   
begin   
  select birthdate into v_birthdate from auths where name='qiuys';   
  --如果查询到一条记录,则删除该记录。   
  if sql%found then   
    delete from auths where name='qiuys';   
  end if;   
exception   
  when no_data_found then   
    dbms_output.put_line('该记录不存在');   
  when too_many_rows then   
    dbms_output_line('存在同名的作家');   
end;  


5、游标变量
到目前为止前面所有显式游标的例子都是静态游标-即游标与一个SQL语句关联,并且该SQL语句在编译时已经确定。
而游标变量是一个引用类型(REF)的变量。
(1)游标变量的声明
declare   
  --使用%rowtype定义一个游标变量类型。   
  type t_authsref is ref cursor return auths%rowtype;   
  --定义一个记录类型。   
  type t_coderecord is record(   
    author_code article.author_code%type,   
    article_code article.article_code%type);   
  --声明一个记录类型的变量。   
  v_code t_coderecord;   
  --使用t_coderecord作为一个游标变量类型的结果集类型。   
  type t_coderef is ref cursor return t_codeRecord;   
  --使用v_code作为一个游标变量类型的结果集类型。   
  type t_coderef2 is ref cursor return v_code%type;   
  --使用上面的类型声明的两个游标变量。   
  v_authcv t_authsref;   
  v_codecv t_coderef;
 

PL/SQL2.8以上版本中,可以使用一个没有指定结果集类型的游标变量来指定多个不同类型的查询。
type t_authsref if ref cursor;
v_cursorvar t_authsref;--声明一个该类型的变量。
(2)打开游标变量
为了将一个游标变更与一个具体的select语句联系起来,open的语法中增加了一个select语句。
open cursor_variable for select_statement;  
declare   
  type t_authorsref is ref cursor return auths%rowtype;   
  v_authscv t_authorsref;   
  --然后打开   
  open v_authscv for select * from auths;  


(3)推进游标变更
(4)关闭游标变更
该操作用来释放查询所占用的资源。但没有释放游标变量占用的存储空间。当变量超出作用域时,它所占用的空间才被释放掉。
下面的块中定义了一个没有指定结果集的游标变量,这样我们就可以使用这个游标变量指向不同的查询,并能够返回不同的记录类型:
set serveroutput on size 100000 --设置存储缓冲区大小。  
declare   
  /*定义游标变更类型t_curref,该游标变量类型没有指定结果集类型,所以该游标变量类型的变量可以返回不同的PL/SQL记录类型。*/  
  type t_curref is ref cursor;   
  --声明一个游标变量类型的变量   
  c_cursorref t_curref;   
  --定义PL/SQL记录类型t_authorrec,该类型的变量用来接收游标变量的返回值。   
  type t_authorrec is record(   
    authorcode auths.author_code%type,   
    name auths.name%type);   
  --定义PL/SQL记录类型t_articlerec,该类型的变量也用来接收游标变量的返回值。   
  type t_articlerec is record(   
    authorcode article.author_code%type,   
    title artitle.title%type);   
  --声明两个记录类型变量。   
  v_author t_authorrec;   
  v_article t_articlerec;   
begin   
  --打开游标变量c_cursorref,返回t_authorrec类型的记录。   
  open c_cursorref for    
    select author_code,name from auths where author_code in('A00001','A00002','A00003','A00004','A00005');   
  --推进游标变量   
  fetch c_cursorref into v_author;   
  --游标变量的推进循环。   
  while c_cursorref%found loop   
    --将作家代码和相应的作家名字输出到屏幕上。   
    dbms_output.put(v_author.authorcode||':'||v_author.name||' ');   
    fetch c_cursorref into v_author;   
  end loop;   
  dbms_output.new_line;--向屏幕上输出一个回车行。   
  --关闭游标变量,仅仅将游标变量指定的资源释放掉,游标变量本身的存储空间没有释放掉。   
  close c_cursorref;   
  --再次打开游标变量,返回t_articlerec类型的记录。   
  open c_cursorref for    
    select author_code,title from article   
    where author_code in('A00001','A00002','A00003','A00004','A00005');   
  fetch c_cursorref into v_article;   
  while c_cursorref%found loop   
    ...   
  end loop;   
  close c_cursorref;   
end;  

注意,在上例中,第一次关闭游标变量是可省略的,因为在第二次打开游标变量时,就将第一次的查询丢失掉了。而且游标变量也有游标属性,通常在推进游标变量时使用这些游标属性,例如上例使用了%found属性。

分享到:
评论

相关推荐

    Oracle显式游标和隐式游标.doc

    Oracle 显式游标和隐式游标 Oracle 中的游标是 SQL 的一个内存工作区,由系统或用户以变量的形式定义。游标有两种类型:显式游标和隐式游标。显式游标是一种明确声明的游标,需要在声明部分使用 CURSOR 语句来定义...

    ORACLE显式游标和动态游标的使用.pdf

    游标分为显式游标、隐式游标和动态游标三种类型。 1. **显式游标**: - 显式游标允许返回多行记录,但在使用之前必须先声明。它适用于查询条件已知的情况。 - 定义显式游标使用`DECLARE`语句,例如:`DECLARE ...

    详解Oracle隐式游标和显式游标

    Oracle数据库提供了两种主要类型的游标:隐式游标和显式游标。 1. **Oracle隐式游标** - **概念**:隐式游标是Oracle在后台自动管理的一种游标,每当执行一个DML(插入、更新、删除)或DDL语句时,系统都会自动...

    Oracle入门--Oracle游标使用

    在Oracle中,游标分为显式游标和隐式游标。 1. **隐式游标**:在PL/SQL中,每次执行DML语句(如SELECT、INSERT、UPDATE、DELETE)时,系统都会自动使用隐式游标。隐式游标提供了一些内置的属性,如%ROWCOUNT(返回...

    oracle 隐式游标,显示游标,游标循环

    游标分为两种主要类型:**隐式游标**和**显示游标**。此外,还可以利用游标进行循环处理,以实现更复杂的数据操作需求。 #### 二、隐式游标 隐式游标是在执行DML(数据操纵语言)操作或单行`SELECT INTO`语句时由...

    Oracle之隐式游标的使用方法.pdf

    隐式游标具有与显式游标类似的属性,包括%FOUND、%NOTFOUND、%ISOPEN和%ROWCOUNT。这些属性可以帮助我们检查操作的状态和结果: - `%ISOPEN`:始终为FALSE,因为隐式游标在每次DML操作后自动关闭。 - `%FOUND`:...

    非常详细的Oracle游标整理

    这里详细介绍了Oracle中的三种游标类型:隐式游标、显式游标和REF游标。 1. **隐式游标**: - 隐式游标是Oracle自动管理和使用的,不需要程序员显式声明。当执行DML(Insert、Delete、Update、Merge into)操作时...

    Oracle数据库实验-PLSQL游标、过程、函数、包的使用[文].pdf

    显式游标需要我们明确地声明、打开、提取、关闭游标,而隐式游标则是由数据库系统自动管理的,通常在DML操作(如INSERT、UPDATE、DELETE)中使用。显式游标提供了更多的控制,例如可以检查是否还有更多行(%NOTFOUND...

    PL/SQL学习笔记6

    显式游标需要显式声明和管理,而隐式游标则由PL/SQL自动处理。 - REF游标是一种引用类型,它像指针一样指向结果集的行,允许更灵活的数据操作。 2. **显式游标**: - 显式游标需通过`CURSOR`关键字声明,并指定一...

    Oracle游标使用案例大全

    6. **隐式游标和显式游标** - 隐式游标:Oracle默认为每一条DML操作隐式创建了一个游标,无需显式声明。 - 显式游标:需要用户声明并管理,适用于更复杂的查询和数据处理场景。 7. **动态SQL与游标** - 动态SQL...

    Oracle游标使用.docx

    游标有两种主要类型:显式游标和隐式游标。 ##### 2.1 显式游标 显式游标是由程序员定义的,用于处理多行数据。它对应于一个多行的SELECT语句,可以用来遍历查询结果集。 ##### 2.2 隐式游标 隐式游标由Oracle自动...

    游标的相关知识和实例

    游标主要分为两类:显式游标和隐式游标。 #### 隐式游标 隐式游标由Oracle自动创建和管理,主要用于DML(数据操纵语言)操作和单行SELECT语句。当执行这些操作时,Oracle会自动创建一个隐式游标来处理数据。隐式...

    Oracle数据库的游标学习总结

    Oracle游标主要分为两大类:显示游标和隐式游标。其中,显示游标又可以根据定义方式的不同细分为静态游标和动态游标。 ##### 显示游标 显示游标主要用于处理SELECT语句的结果集。当定义游标时,需要明确指定SQL...

    Oracle游标

    隐式游标是Oracle在执行DML(数据操纵语言)语句如SELECT INTO、UPDATE、INSERT和DELETE时自动创建和管理的。对于只处理单行数据的操作,系统会自动打开、使用并关闭隐式游标。例如,以下示例展示了如何检查UPDATE...

    Oracle之认识游标.pdf

    游标主要分为隐式游标和显式游标: - 隐式游标:由系统自动创建和管理,无需用户显式声明。对于任何SQL数据操作,包括返回一条记录的查询,都会有一个隐式游标。用户可以通过访问隐式游标的属性来获取信息。 - 显式...

    Oracle游标使用方法及语法大全

    - 当执行单行SELECT语句(如`SELECT INTO`)时,Oracle会自动使用隐式游标。它在后台打开,处理查询后自动关闭。用户无需显式声明或管理。 - 隐式游标提供了几个百分比属性,如 `%FOUND`(查询是否找到数据),`%...

    Oracle显式游标的使用.pdf

    显式游标适用于那些查询条件已知且可能返回多行记录的情况,与隐式游标(在执行SELECT、DML语句时自动使用的游标)和动态游标(查询条件在运行时才能确定)不同。 显式游标的使用步骤如下: 1. **定义游标**:通过...

    游标和异常处理 游标和异常处理

    游标有两种类型:隐式游标和显式游标。在前述程序中用到的SELECT...INTO... 查询语句,一次只能从数据库中提取一行数据,对于这种形式的查询和 DML 操作,系统都会使用一个隐式游标。但是如果要提取多行数据,就要由...

    plsql 游标 英文讲义

    在PL/SQL(Procedure Language extensions to SQL)中,游标分为隐式游标和显式游标两种。 首先,我们来看隐式游标的概念。隐式游标是由PL/SQL在执行SQL SELECT或DML(Data Manipulation Language)语句时自动创建...

Global site tag (gtag.js) - Google Analytics