游标是构建在L/SQL中用来查询数据库、获取记录集合(结果集)的指针,它使开发人员能够一次访问一行结果集。为了处理SQL语句,Oracle将在内存中分配一个区域,这就是上下文区。这个区包含了已经处理完的行数、指向被分析语句的指针,整个区是查询语句返回的数据行集。游标就是指向上下文区句柄或指针。两种游标:
- 显示游标:显示游标被用于处理返回多行数据的SELECT语句,游标名通过CURSOR….IS 语句显示地赋给SELECT 语句。在PL/SQL中处理显示游标所必需的四个步骤:
- 声明游标:
CURSOR cursor_name IS select_statement
- 打开游标:
OPEN cursor_name
- 取得结果放入PL/SQL变量中:
FETCH cursor_name INTO list_of_variables; FETCH cursor_name INTO PL/SQL_record;
- 关闭游标:
注意:在声明游标时,select_statement不能包含INTO子句。当使用显示游标时,INTO子句是FETCH语句的一部分。CLOSE cursor_name
- 声明游标:
- 隐式游标:所有的隐式游标都被假设为只返回一条记录。使用隐式游标时,用户无需进行声明、打开及关闭。PL/SQL隐含地打开、处理,然后关掉游标。
四种常用的游标例子:
- FOR循环游标:
declare -- 类型定义 cursor my_cursor is select empno,ename,job,sal from emp where job = 'MANAGER'; begin -- for 循环 for cursor_record in my_cursor loop dbms_output.put_line(cursor_record.empno||'-'||cursor_record.ename ||'-'||cursor_record.job||'-'||cursor_record.sal); end loop; end;
- Fecth游标:
游标的4种属性:/* * Fetch游标 */ declare -- 类型定义 cursor my_cursor is select empno, ename, job, sal from emp where job = 'MANAGER'; -- 定义一个游标变量 l_cursor my_cursor%rowtype; begin -- 打开游标 open my_cursor; -- loop循环 loop -- 提取一行数据到l_cursor变量中 fetch my_cursor into l_cursor; exit when my_cursor%notfound; dbms_output.put_line(l_cursor.empno||'-'||l_cursor.ename|| '-'||l_cursor.job||'-'||l_cursor.sal||'-'||my_cursor%rowcount); end loop; -- 关闭游标 close my_cursor; end;
- %notfound fetch是否提到数据 没有true 提到false
- %found fetch是否提到数据 有true 没提到false
- %rowcount 已经取出的记录的条数
- %isopen 布尔值 游标是否打开
- 参数游标:
/* * 参数游标 */ declare -- 获得部门 cursor my_cursor1 is select deptno from dept; -- 定义游标参数,只能指定类型,不能指定长度 cursor my_cursor2(no number, pjob varchar2) is select emp.* from emp where deptno = no and job = pjob; begin for cursor_record1 in my_cursor1 loop -- 参数在游标中使用 for cursor_record2 in my_cursor2(cursor_record1.deptno, 'MANAGER') loop dbms_output.put_line(cursor_record2.deptno || '-' || cursor_record2.ename); end loop; end loop; end;
- 引用游标/动态游标:
/* * 引用游标/动态游标 */ declare -- 定义一个弱类型的ref cursor type weakly_cursor is ref cursor; -- 定义一个强类型的ref cursor type strongly_cursor is ref cursor return dept%rowtype; -- 定义ref cursor类型的变量 w_cursor weakly_cursor; s_cursor strongly_cursor; -- 定义记录 emp_record emp%rowtype; dept_record dept%rowtype; begin dbms_output.put_line('输出员工'); open w_cursor for select * from emp; loop fetch w_cursor into emp_record; exit when w_cursor%notfound; dbms_output.put_line(emp_record.ename); end loop; close w_cursor; dbms_output.put_line('输出部门'); open s_cursor for select * from dept; loop fetch s_cursor into dept_record; exit when s_cursor%notfound; dbms_output.put_line(dept_record.dname); end loop; close s_cursor; end;