Oracle游标管理

原创 2012年03月26日 18:51:27
--游标	
--在PL/SQL中 内存中记录集合的指针,指向一行,提供逐行访问记录
--在初始状态下指向的是首记录

--游标的属性:
	%found
   	%notfound
	%isopen
	%rowcount 


--Oracle 游标分为  显式游标和隐式游标

--隐式游标
--PL/SQL 中用户在使用数据操作语言(DML)时,预先定义一个名SQL的隐式游标
--用户不能直接控制此游标,但可以通过检查隐式游标的属性获取信息
--执行DML语句后,Oracle自动关闭
begin
      update scott.emp set sal=sal+1 where deptno=50;
      if SQL%found then
           dbms_output.put_line('表已更新...'||sql%rowcount||'行记录');
      else
           dbms_output.put_line('没有找到记录....');
      end if;
     if not sql%isopen then
           dbms_output.put_line('sql游标已经关闭');
      end if;
      commit;
end;



--显式游标     用户自定义的游标
  
--一般使用步骤:  
     --声明游标: cursor 游标名 is 查询语句 ;
     --打开游标: open 游标名;
     --提取游标:  fetch  游标名 into 变量;
     --关闭游标:  close 游标名
declare
 	cursor v_cs is select * from scott.emp; 	--声明游标
 	v_temp v_cs%rowtype;           
begin
  	open v_cs;                             			--打开游标
  	loop
    	fetch v_cs into v_temp;              		--提取游标
    	dbms_output.put_line(v_temp.ename ||'    '||v_temp.hiredate);
    	exit when v_cs%notfound;            		 --如果游标没有记录退出循环
  	end loop;
  	close v_cs;                              		--关闭游标
end;

--游标属性说明
declare
    v_dept number;
    cursor v_cur is select * from scott.emp where deptno=v_dept;
    c_temp v_cur%rowtype;
begin
    v_dept:=30;
    open v_cur;
    dbms_output.put_line('fetch前游标总记录数:'||v_cur%rowcount);
    if(v_cur%isopen) then
         dbms_output.put_line('游标已经打开');
    end if;
    loop
       fetch v_cur into c_temp;
       dbms_output.put('游标总记录数:'||v_cur%rowcount||' ');
       if(v_cur%found) then   
           dbms_output.put_line(c_temp.ename||'  '||c_temp.sal);
       else
           dbms_output.put_line('游标已经没有记录');
           exit;
       end if;
   end loop;
   close v_cur;
end;


/*带参数的游标
   声明:  cursor 游标名(形参 数据类型...) is select.... where ...=形参;
   使用: open  游标名(实参);
*/
declare
 		v_input scott.emp.deptno%type;
 		v_name scott.emp.ename%type;
 		v_sal scott.emp.sal%type;
 		cursor c_cur(v_param number) is select ename,sal from scott.emp where deptno=v_param;
begin
 		v_input:='&部门编号';
 		open c_cur(v_input);  --传入实参
 		loop
   		fetch c_cur into v_name,v_sal;
   		exit when c_cur%notfound;
   		dbms_output.put_line(v_name||'   '||v_sal);
 		end loop;
 		close c_cur;
end;


/*
用于delete/update的游标  
声明时指定  for update [of 列] [nowait]   加行级锁  
[of 列] 如果涉及到多张表,默认会在所有表上加行共享锁,
为了只在特定表上加行共享锁,需要在for update子句后带有of子句指定字段名  
 更新时   update ......where current of 游标名
*/
declare 
      cursor c_cur is select * from scott.emp  for update ;
      v_temp emp%rowtype;
begin
     open c_cur;
     loop
       fetch c_cur into v_temp;
       exit when c_cur%notfound;
       if(v_temp.sal<1000) then
               update scott.emp set sal=sal+1 where current of c_cur;
       end if;
     end loop;
     close c_cur;
     commit;
end;


/*
   for 循环游标
          自动打开,关闭,自动获取记录
   声明游标:  cursor cursor_name is select......
   使用:      for  v_name  in cursor_name(或select语句)
              loop.....end loop;
*/
--例1
declare
  		cursor c_cur is select * from scott.emp;
begin 
  		for v_temp in c_cur  loop  --v_temp局部变量,无需声明
  				dbms_output.put_line(v_temp.ename||'  '||v_temp.sal);
  		end loop;
end;  
--例2
declare
       v_input varchar2(1);
begin
      v_input:='&请选择';
      if v_input='a' then
         for v_rec in (select * from emp)
         loop
             dbms_output.put_line(v_rec.empno||':'||v_rec.ename||' '||
v_rec.hiredate||'  '||v_rec.sal);
         end loop;
      elsif v_input='b' then
         for v_rec in (select * from dept)
         loop
            dbms_output.put_line(v_rec.deptno||':'||v_rec.dname);             
         end loop;
      else
         dbms_output.put_line('please input...');
         return;
      end if; 
end;



/********* for 循环游标(带参数) *************
      声明游标:  cursor cursor_name(形参列表) is select......
      使用:   for  v_name  in cursor_name(实参)
              loop.....end loop;
****/

declare
   v_input emp.deptno%type;
   cursor c(dept number) is select * from emp where deptno=dept ; 
begin 
    v_input:='&部门编号';
    for v_rec in c(v_input)  loop
       dbms_output.put_line(v_rec.ename||':'||v_rec.sal);
    end loop;
end;



/**************  ref cursor游标*******************
用于处理运行时动态执行的 SQL查询 即在open游标时动态指定sql语句
声明ref cursor类型 :    
TYPE <ref_cursor_name> IS REF CURSOR [RETURN <return_type>];
    声明ref游标类型的游标变量:  变量名  游标名;
    打开方式:     open cursor_name for 查询语句
***/
声明强类型的 REF 游标:
TYPE t_refcur IS REF CURSOR RETURN emp%ROWTYPE; 
V_cur t_refcur;

声明弱类型的 REF 游标 (用于动态SQL)
TYPE t_refcur IS REF CURSOR; 
V_cur t_refcur;

declare
     type v_refcur is ref cursor;		-- -声明 ref cursor 类型
     refcur v_refcur;    			       --声明 ref cursor 类型的游标变量
     v_id number;
     v_name varchar2(20);
     v_selection varchar2(1):=upper(substr('&请输入员工(E)或部门编号(D)',1,1));
     begin
          if v_selection='E' then
             open refcur for select empno,ename from emp;	--打开游标
             dbms_output.put_line('====员工信息====');
          elsif v_selection='D' then
             open refcur for select deptno,dname from dept; --打开游标
             dbms_output.put_line('====部门信息====');
          else
              dbms_output.put_line('请输入员工信息(E)或部门信息(D)');
              return;   -- 返回
          end if;
          fetch refcur into v_id,v_name;-- 提取游标
          while refcur%found  loop
                  dbms_output.put_line('#'||v_id||':'||v_name);
                  fetch refcur into v_id,v_name;
          end loop;
          close refcur;  -- 关闭游标
end;



/*******动态SQL(使用ref cursor 返回多行记录)***********
    使用占位符
     Open cursor_name for v_sql [using 占位符对应的变量]
*****/
declare
   type v_refcur is ref cursor;
   v_cur v_refcur;
   v_emp emp%rowtype;
   v_salary number;
   v_sql varchar2(100);
   v_dno number;
begin
    v_salary :='&请输入薪水标准';
    v_dno:='&请输入部门编号';
   v_sql:='select * from emp where sal>:1 and deptno=:2 order by sal desc';
   open v_cur for v_sql  using  v_salary,v_dno;
   dbms_output.put_line('薪水大于'||v_salary ||'的员工:');
   loop
     fetch v_cur into v_emp;
     exit when v_cur%notfound;
     dbms_output.put_line('姓名: '||v_emp.ename||' 薪水: '||v_emp.sal);
   end loop;
   close v_cur;
end;

源码-Oracle数据库管理-第十五章-触发器和游标-Part 1(理解触发器)

纸上得来终觉浅,绝知此事要躬行。 --15.1.2 定义触发器 --15.1.3 触发器的分类 --15.2 DML触发器 --15.2.1 触发器的执行顺序 --1. 单行触发器的执行顺序 --2...

源码-Oracle数据库管理-第十五章-触发器和游标-Part 3(理解触发器)

一边听着动人的古典音乐,一边敲着代码(SQL脚本也算是代码吧:)),用这种方式迎接新的一年的到来,也算是一种全新的体验吧。 --代码15.11 为视图创建替代触发器 --创建一个连接emp和dept...

【安博培训笔记】Oracle6 游标管理 作业20130911

Oracle6 游标管理 作业 create user shihua identified by shihua; grant connect,resource to shihua; 一、按下列...

源码-Oracle数据库管理-第十五章-触发器和游标-Part 2(理解触发器)

利用触发器,可以让Oracle自动完成一些任务,如,日志记录,比较有意思。 心得:在PL/SQL Developer工具中,在script中运行 create or replace trigger ...

源码-Oracle数据库管理-第十五章-触发器和游标-Part 4(理解触发器)

触发器在目前为止的工作中接触不多,却是我感觉很有趣的部分,有机会再好好用用。 --代码15.15 使用DDL触发器监控方案对象的创建 --在scott用户模式下创建一个保存DDL创建信息的表, CR...

ORACLE数据库 游标管理基础

游标是构建在PL/SQL中的,主要用来查询数据,获得记录集的指针.一些对数据表的复杂操作我们都可以通过游标来进行。以下代码是在PLSQL Developer 6.0环境中运行的。为了方便,我们使用 s...

Oracle 数据库 11g新特性:自适应游标与 SQL 计划管理

原文地址:http://blog.chinaunix.net/uid-42518-id-2404640.html到目前为止,很多人都已经了解大量使用绑定变量来提高性能的方法;对于尚不清楚这种方法的用户...

源码-Oracle数据库管理-第十五章-触发器和游标-Part 2(理解游标)

游标在目前的实际工作中接触也不多,希望以后有机会深入学习一下。 --代码15.18 在PL/SQL中使用隐式游标 BEGIN UPDATE emp SET comm = comm ...

Oracle游标使用详解

  • 2011年07月06日 10:21
  • 4KB
  • 下载

Oracle中PLSQL游标

  • 2012年07月25日 15:17
  • 524KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Oracle游标管理
举报原因:
原因补充:

(最多只允许输入30个字)