--=============cursor:在pl/sql中用来 处理多行多列(包括0行) 的记录数据===================== -- Cursor: oracle使用专有的sql 工作区(private sql workparea)来执行sql语句,存储信息.这个工作区称之为cursor --oracle每执行每一个sql语句都有唯一的cursor与之对应. --2.游标的分类 ----显示游标:即用户自定义游标,专门用于处理select语句返回的多行数据 ----隐式游标:系统自动定义的游标,记录集只有单行数据,用于处理select into 和DML语句 --3.游标使用的一般过程: ----显式游标:声明(declare), 打开(open,执行sql语句,产生结果集), 读取(fetch,提取结果集中记录), 关闭(close) ------显示cursor的属性: ------属性 类型 描述 ------%isopen boolean open--> true ------%notfound boolean 前一个fetch没有返回一行记录-->true ------%found boolean 前一个fetch返回一行记录-->true,同%notfound相反. ------%rowcount number 到目前为止 cursor已提取的总行数 ----隐式游标:直接使用读取,声明、打开、关闭都是系统自动进行的 ------隐式cursor的属性: ------ 属性 类型 描述 ------SQL%isopen boolean dml执行为true,结束后false; ------SQL%notfound boolean sql%found属性返回值相反 ------SQL%found boolean dml操作成功 true ------SQL%rowcount number dml执行成功的数据行数 --======显式游标============================================ ---=============================================================================== declare --声明游标: Cursor is select xxx ; 在没有open之前 不会执行该select语句 Cursor c_emp is select * from emp where deptno = 10 or deptno = 20; v_emp emp%rowtype; --声明变量,用来接收从cursor中的取出的每一条数据 begin open c_emp; --打开cursor ,开始执行select 语句 loop --循环读取cursor结果 fetch c_emp into v_emp; --从结果集中取数据到v_emp变量,并移动指向数据的指针 if c_emp%FOUND --如果上一个fetch找到记录 就返回true . then dbms_output.put_line(v_emp.ename); else EXIT; end if; end loop; close c_emp; --关闭close,释放资源 end; --2.record类型 + while处理cursor declare -- 定义record类型 type r_emp_rec is record( eid emp.empno%type, name emp.ename%type ); Cursor c_emp_cursor is select empno , ename from emp where empno = 7900; v_emp r_emp_rec;--声明 v_emp 记录类型的变量 begin open c_emp_cursor; --必须先fetch,c_emp_cursor%found的值才会是true或false, - --若不fetch, c_emp_cursor%found的值为null fetch c_emp_cursor into v_emp; --通过循环处理结果集中的数据,若c_emp_cursor%Found的值为false,循环结束 while c_emp_cursor%FOUND LOOP dbms_output.put_line(v_emp.name); fetch c_emp_cursor into v_emp; --再次fetch end loop; close c_emp_cursor; end; / -- 3 . record类型 + for处理cursor +游标参数 -- ----For循环对cursor的处理进行了集成, ------ 不需要open、循环处理fetch、close。cursor中的数据通过for循环中的记录类型的变量emp执行引用。 declare -- type t_emp_rec is record( -- salary emp.sal%type, name emp.ename%type -- ); -- v_emp t_emp_rec; Cursor c_emp(emp_id number) is -- emp_id是参数 select sal , ename from emp where empno = emp_id; begin for emp in c_emp(7900) LOOP dbms_output.put_line(emp.ename); end LOOP; end ; / --===========总结============== --cursor的声明 ----1.在游标声明中使用标准的select 语句 ----2.查询中可以用order by来处理次序问题。 ----3.可以在查询中引用变量,但必须在cursor语句之前声明这些变量. Cursor c_emp_id(emp_id number) is select id from service where cost_id = emp_id; --open cursor ----通过open cursor来执行select语句 并标识结果集. ----select语句没有记录返回 不会出现异常. ----open cursor emp_id(5); --fech cursor. ----1.检查当前行 ,把值赋给变量.变量可以是record类型或者标量类型 ----2. fetch cursorName into 变量1,变量2 | record_name ; --cursor结果集处理 ----1.使用loop处理cursor. ----2.每次fetch一行,反复进行. ----3.使用%notfound属性检测一次不成功的提取操作 ----4.使用显示cursor的属性检测提取是否成功,避免死循环. --关闭cursor ----1.最后一条记录,应该关闭cursor.(有需要,可以再次open) ----2,cursor一旦关闭,所有和当前cursor相关的资源都会释放,不能从关闭的 cursor中fetch数据. ----3.对任何关闭的cursor的操作都会invalid_cursor错误。 ----4.每个session打开的cursor数量由open_cursor参数决定 --===========练习================= -- 打印每个员工的ename , id ,不存在则打印not exists; declare Cursor c_emp is --select * from emp where 1 = 2; -- 模拟没有查询到记录 select * from emp where 1 = 1; v_emp emp%rowtype; begin open c_emp; fetch c_emp into v_emp; if c_emp%FOUND then while c_emp%FOUND LOOP dbms_output.put_line(v_emp.ename ||'--------------'|| v_emp.deptno); fetch c_emp into v_emp; exit when c_emp%NOTFOUND; end loop; else dbms_output.put_line('not exists'); end if; close c_emp; end; /
Oracle数据库之PLSQL游标
猜你喜欢
转载自whatisjavabean.iteye.com/blog/2003432
今日推荐
周排行