21.6 使用游标
Oracle游标是内存中一个区域的句柄,它保存一个SQL査询的结果集,从而能够单独地处理结果集中的行。Oracle对所有DML语句使用隐式游标(implicit cursor),而显式游标由应用开发人员创建和使用。
21.6.1 隐式游标
每当用户在PL/SQL中使用一条SELECT语句时,Oracle都将自动使用一个隐式游标。你可以在返回一行的语句中使用隐式游标如果SQL语句返回多行,将出现错误.
在下面的PL/SQL代码块中,SELECT语句使用了一个隐式游标:
DECLARE
empname varchar2(4O);
salary float;
BEGIN
SELECT empname, salary FROM employees WHERE employee_id=9999;
dbms_output.put_line('employeename : '||empname||' salary :'||salary);
END;
/
21.6.2 显式游标
显式游标由应用开发人员创建,它方便执行具有一组可逐行处理的行操作。确定SQL语句将返回多行时,应该使用显式游标。请注意,与隐式游标(你永远不必在代码中引用它)不同,显式游标必须在PL/SQL块开始处的DECLARE部分声明,
声明了显式游标后,它将经历如下步骤:
(1)OPEN子句将确定游标中的行,.使其可供PL/SQL程序使用。
(2)FETCH命令将游标中把数据存入某个特定的变量中。
(3)在处理完成后,应该显式地关闭游标。
使用显式游标
DECLARE
/* The cursor select_emp is explicitly declared */
CURSOR select_emp IS select empid, city from employees where city = 'DALLAS';
v_empno employees.emp_id%TYPE;
v_empcity employees.city%TYPE;
BEGIN
/* The cursor select_emp is opened */
Open select_emp;
LOOP
/* The select_emp cursor data is fetched into v_empno vaiiable */
FETCH select_emp into v_empno;
EXIT WHEN select_emp%NOTFOUND;
dbms_output.put_iine(v_empno|| ',' ||v_empcity);
END LOOP;
/* The cursor select_emp is closed */
Close select_emp;
END;
/
21.6.3 游标属性
在代码淸单A-4给岀的例子中,使用了一个特殊的游标属性%NOTFOUND表示何时结束循环。游标属性在处理显式游标时非常有用。下面给出主要的游标属性:
1. %ISOPEN是一个布尔属性,在游标未打开时其值为假。游标打开后,它返回真。
2. %FOUND是一个布尔属性,它测试是否有与SQL语句匹配的行,即游标中是否有更多的行可供取出。
3. %NOTFOUND是一个布尔属性,值为真表示没有与SQL语句匹配的行,即游标中没有更多的行可供取出。
4. %ROWCOUNT给岀到现在为止从游标中取出的行数。
游标FOR循环
一般在使用显式游标时,必须打开游标,取出游标中的数据,然后关闭游标。游标FOR循环自动执行打开、取数据和关闭操作,这简化了工作。
21.6.4 使用游标FOR循环
DECLARE
CURSOR emp_cursor IS SELECT empid, empname, salary FROM employees;
v_empinfo employees%RowType;
Begin
FOR empinfo IN emp_cursor
LOOP
dbms_output.put_line ('Employee id : '||emp_id||'Employee
name : '||empname||'Employee salary :' ||salary);
END LOOP;
END;
/
21.6.5 游标变量
游标变量(cursor variable)指出一个多行结果集中的当前行。与普通游标不同,游标变量是动态的,既可以给游标变量赋新值,也可将其值传递给其他过程和函数。我们来看一下如何在PL/SQL中创建游标变量。
首先,定义一个REF CURSOR类型,如下例所示:
DECLARE
TYPE EmpCurTyp IS REF CURSOR RETURN dept%ROWTYPE;
接着,在一个匿名PL/SQL代码块或一个过程(或函数)中,声明类型为EmpCurTyp的游标变量, 如下面的代码片段所示:
DECLARE
TYPE EmpRecTyp IS RECORD (
Emp_id NUMBER(9),
emp_name VARCHAR2(30),
sal NUMBER(7,2));
TYPE EmpCurTyp IS REF CURSOR RETURN EmpRecTyp;
emp_cv EmpCurTyp; -- declare cursor variable