在pl/sql程序中,对于处理多行记录的事务经常使用游标来实现。当执行查询语句或者数据操纵语句是,一般可能会产生或者处理一组记录。游标是为了处理这些记录而分配的一段内存区。
游标分为:显示游标和隐示游标。当记录集中只有单行数据时,系统自动的进行定义右边,称为隐示游标。记录集中含有多行数据时,需要用户自己定义游标,称为显示游标。下面分别进行介绍。
显示游标
显示游标的处理需四个使用步骤:
1.定义游标: 就是定义一个游标名,以及与其对应的select 语句。 格式: cursor cursor_name is select_statement 。 2.打开游标: 游标定义之后,要使用游标中的数据,就要打开游标。使用open打开游标。游标只能打开一次。 open cursor_name 。 3.提取游标数据: 检索游标结果集中的数据,放入指定的变量之中。 格式: fetch cursor_name into variable_name 。 4.关闭游标: 游标使用完成之后,应该及时的关闭游标,将系统资源释放。 close cursor_name 。
游标属性
%found :布尔型,判断最近一次执行fetch语句后,是否从缓冲区中提取到数据,如果提取到数据,返回ture,否则返回false。 %notfound:布尔型,与%found相反,没有提取到数据返回true,否则返回false。 %isopen :布尔型,当游标打开的时候返回true。 %rowcount:数字型,放回已从游标中读取的记录数。
例:使用游标数据10号部门的员工工资。
declare --定义变量 v_sal emp.sal%type ; --定义游标 cursor emp_sal_cursor is select sal from emp where deptno = 10 ; begin --打开游标 open emp_sal_cursor ; --提起游标信息 fetch emp_sal_cursor into v_sal ; while emp_sal_cursor%found loop dbms_output.put_line(v_sal); fetch emp_sal_cursor into v_sal ; end loop ; --关闭游标 close emp_sal_cursor; end ;
例:使用记录类型和游标检索数据
--定义变量 typeemp_record is record( v_salemp.sal%type , v_idemp.empno%type ); v_emp_record emp_record ; cursor emp_sal_cursor is selectsal ,empno from emp where deptno = 10 ; --打开游标 openemp_sal_cursor ; --提起游标信息 fetch emp_sal_cursor into v_emp_record ; while emp_sal_cursor%found loop dbms_output.put_line(v_emp_record.v_sal ||‘, ‘|| v_emp_record.v_id); fetch emp_sal_cursor into v_emp_record ; end loop ; --关闭游标 close emp_sal_cursor;
游标的for循环
pl/sql语言提供了游标for循环语句,自动执行游标的open,fetch,close语句和循环语句的功能,当进入循环式,游标for循环语句自动打开,并提取第一行游标数据,当程序处理完当前所提取的数据而进入下一次循环式,游标for循环语句自动的提取下一行的数据,当提取晚结果集合中所有的数据行后自动结束循环,并自动关闭游标。
for index_var in cursor_name loop --处理代码 end loop ;
例:使用for循环检索数据
cursor emp_sal_cursor is select * from emp where deptno = 10 ; for c in emp_sal_cursor loop dbms_output.put_line(c.sal ||‘, ‘|| c.hiredate); end loop ;
例:使用游标和for循环更新数据
cursoremp_sal_cursorisselect empno,sal fromemp ; v_empnumber(4 ,2 ) ; begin forcinemp_sal_cursorloop ifc.sal <1000thenv_emp := 0.05 ; elsifc.sal <2000thenv_emp := 0.03 ; elsifc.sal <5000thenv_emp := 0.02 ; elsev_emp := 0.01 ; endif ; dbms_output.put_line(c.sal ||‘,‘|| c.empno); updateempsetsal = sal* (1+ v_emp) whereempno = c.empno ; endloop ;
带参数的游标
游标在定义的时候,可以带参数。参数在指定数据类型时,不能指定它的长度。
例:当声明的游标带有参数时,通过游标for循环语句来为游标传递参数
cursor c_emp(dept_no number ) is select sal , ename from emp here deptno = dept_no ; for c in c_emp(20) loop dbms_output.put_line(c.sal || ‘,‘||c.ename); end loop ;
end
隐示游标
不需要显示的定义游标。调用格式:sql% ; update emp set sal = sal +100 where empno = 7444 ; if sql%notfound then dbms_output.put_line(‘没有此人‘); end if ;