对于DML语句和单行select into ,oracle自动分配隐形游标。处理select返回多行语句,可以使用显式游标。
使用显示游标处理多行数据,也可使用SELECT..BULK COLLECT INTO 语句处理多行数据.
cursor cursor_name is select_statement;
执行对应的SELECT语句并将SELECT语句的结果暂时存放到结果集中.
open cursor_name;
打开游标后,SELECT语句的结果被临时存放到游标结果集中,使用FETCH语句只能提取一行数据
通过使用FETCH..BULK COLLECT INTO语句每次可以提取多行数据
fetch cursor_name into variable1,varibale2,...; fetch cursor_name bulk collect into collect1,collect2,...[limit rows];
(1)游标中使用fetch..into语句:只能处理一行数据,除非用循环语句
declare v_bookname varchar2(100); cursor c_book(i_id number) is select bookname from book where id = i_id; begin Open c_book(10);--打开游标 Loop Fetch c_book into v_bookname; --提取游标 exit when c_book%notfound; update book set price = "33" where bookname = v_bookname; End Loop; Close c_book;--关闭游标 end;
或
declare v_bookname varchar2(100); cursor c_book(i_id number) is select bookname from book where id = i_id; begin Open c_book(10); Fetch c_book into v_bookname;--预先Fetch一次 While c_book%found Loop update book set price = "33" where bookname = v_bookname; Fetch c_book into v_bookname; End Loop; Close c_book; end;
(3)基于游标定义记录变量
declare cursor emp_cursor is select ename,sal from emp; emp_record emp_cursor%rowtype; begin open emp_cursor; loop fetch emp_cursor into emp_record; exit when emp_cursor%notfound; dbms_output.put_line("雇员名:"||emp_record.ename||",雇员工资:"||emp_record.sal); end loop; end;
close cursor_name;
用于返回显示游标的执行信息,包括%isopen,%found,%notfound,%rowcount
no_data_found和%notfound的用法是有区别的,小结如下1)SELECT. . . INTO 语句触发 no_data_found;
2)当一个显式光标(静态和动态)的 where 子句未找到时触发 %notfound;
3)当UPDATE或DELETE语句的where 子句未找到时触发 sql%notfound;
4)在光标的提取(Fetch)循环中要用 %notfound 或%found 来确定循环的退出条件,不要用no_data_found。
注意:定义参数游标时,游标参数只能指定数据类型,而不能指定长度。
declare cursor emp_cursor(no number) is select ename from emp where deptno=no; v_ename emp.ename%type; begin open emp_cursor(10); loop fetch emp_cursor into v_ename; exit when emp_cursor%notfound; dbms_output.put_line(v_ename); end loop; close emp_cursor; end;
使用FOR循环时,ORACLE会隐含的打开游标,提取游标数据并关闭游标。
每循环一次提取一次数据,在提取了所有数据后,自动退出循环并隐含的关闭游标。
1.使用游标FOR循环
--不需要声明v_bookname,Open和Close游标和fetch操作(不用打开游标和关闭游标,实现遍历游标最高效方式) declare cursor c_book(i_id number) is select bookname from book where id = i_id; begin for cur in c_book(10) loop --循环变量cur不需要声明 update book set price = "53" where bookname = cur.bookname; end loop; end;
2.在游标FOR循环中直接使用子查询
begin for emp_record in (select ename,sal from emp) loop dbms_output.put_line(emp_record.ename); end loop; end;
要通过游标更新或删除数据,在定义游标时必须要带有FOR UPDATE子句
cursor cursor_name(parameter_name datetype) is select_statement for update [of column_reference] [nowait];
declare cursor emp_cursor is select ename,sal from emp for update; v_ename emp.ename%type; v_sal emp.sal%tyep; begin open emp_cursor; loop fetch emp_cursor into v_ename,v_oldsal; exit when emp_cursor%notfound; if v_oldsal<2000 then update emp set sal=sal+100 where current of emp_cursor;--delete from emp where current of emp_cursor; end if; end loop; close emp_cursor; end;
将查询结果一次性加载到集合中,而不是一条一条的加载。
(1)在显示游标中,使用FETCH..BALK COLLECT INTO语句提取所有数据
declare cursor emp_cursor is select ename from emp where deptno=10; type ename_table_type is table of varchar2(10); ename_table ename_table_type; begin open emp_cursor; fetch emp_cursor bulk collect into ename_table; for i in 1..ename_table.count loop dbms_output.put_line(ename_table(i)); end loop; close emp_cursor; end;
(2)游标中使用FETCH..BULK COLLECT INTO ..LIMIT语句提取部分数据
declare type name_array_type is varray(5) of varchar2(10); name_array name_array_type; cursor emp_cursor is select ename from emp; rows int:=5; v_count int:=0; begin open emp_cursor; loop fetch emp_cursor bulk collect into name_array limit rows; dbms_output.pur("雇员名"); for i in 1..(emp_currsor%rowcount-v_count) loop dbms_output.put(name_array(i)||" "); end loop; dbms_output.new_line; v_count:=emp_cursor%rowcount; exit when emp_cursor%notfound; end loop; close emp_cursor; end;
PL/SQL的游标变量中存放着指向内存地址的指针.
包括定义游标变量,打开游标,提取游标数据,关闭游标等四个阶段
type ref_type_name is ref cursor [return return_type]; cursor_varibale ref_type_name;
当指定RETURN子句时,其数据类型必须是记录类型,不能在包内定义游标变量
open cursor_variable for select_statement;
fetch cursor_varibale into variable1,variable2,...; fetch cursor_varibale bulk collect into collect1,collect2,...[limit rows]
close cursor_varibale;
1、在定义FEF CURSOR类型时不指定RETURN子句
在打开游标时可以指定任何的SELECT语句
declare type emp_cursor_type is ref cursor; emp_cursor emp_cursor_type; emp_record emp%rowtype; begin open emp_cursor for select * from emp where deptno=10; loop fetch emp_cursor into emp_record; exit when emp_cursor%notfound; dbms_output.put_line("第"||emp_curosr%rowcount||"个雇员: "||emp_record.ename); end loop; close emp_cursor; end;
2、在定义REF CURSOR类型时指定RETURN子句
在打开游标时SELECT语句的返回结果必须与RETURN子句所指定的记录类型相匹配.
declare type emp_record_type is record(name varchar2(10),salary number(6,2)); type emp_cursor_type is ref cursor return emp_record_type; emp_cursor emp_cursor_type; emp_record emp_record_type; begin open emp_cursor for select ename,sal from emp where deptno=20; loop fetch emp_cursor into emp_record; exit when emp_cursor%notfound; dbms_output.put_line("第"||emp_curosr%rowcount||"个雇员: "||emp_record.ename); end loop; close emp_cursor; end;
到此这篇关于Oracle中游标Cursor用法的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持。
相关文章: