- 声明游标;CURSOR cursor_name IS select_statement
--For 循环游标
--(1)定义游标
--(2)定义游标变量
--(3)使用for循环来使用这个游标
declare cursor c_job is select id,name,pid from emp; --定义游标 c_row c_job%rowtype; --定义一个游标变量v_cinfo c_emp%ROWTYPE ,该类型为游标c_emp中的一行数据类型 begin for c_row in c_job loop dbms_output.put_line(c_row.id||'-'||c_row.name||'-'||c_row.pid); end loop; end;
--Fetch游标
--使用的时候必须要明确的打开和关闭
--3,使用游标和fetch declare cursor c_job is select id, name, pid from test; c_row c_job%rowtype; begin open c_job; loop fetch c_job into c_row; --提取一行数据到c_row exit when c_job%notfound; --判读是否提取到值,没取到值就退出 --取到值c_job%notfound 是false --取不到值c_job%notfound 是true dbms_output.put_line(c_row.id||'-'||c_row.name||'-'||c_row.pid); end loop; close c_job; --关闭游标 end;
--3,几种常规的判断语句,防止报错 empNumber emp.EMPNO%TYPE; empName emp.ENAME%TYPE; begin if sql%isopen then dbms_output.put_line('Cursor is opinging'); else dbms_output.put_line('Cursor is Close'); end if; if sql%notfound then dbms_output.put_line('No Value'); else dbms_output.put_line(empNumber); end if; dbms_output.put_line(sql%rowcount); dbms_output.put_line('-------------'); select EMPNO,ENAME into empNumber,empName from emp where EMPNO=7499; dbms_output.put_line(sql%rowcount); if sql%isopen then dbms_output.put_line('Cursor is opinging'); else dbms_output.put_line('Cursor is Closing'); end if; if sql%notfound then dbms_output.put_line('No Value'); else dbms_output.put_line(empNumber); end if; exception when no_data_found then dbms_output.put_line('No Value'); when too_many_rows then dbms_output.put_line('too many rows'); end;
--3,使用游标和while循环 declare cursor csr_TestWhile is select name from test; row_loc csr_TestWhile%rowtype; begin open csr_TestWhile; fetch csr_TestWhile into row_loc; while csr_TestWhile%found loop --测试是否有数据,并执行循环 dbms_output.put_line('人员名称:'||row_loc.name); fetch csr_TestWhile into row_loc; -- 遍历数据 end loop; close csr_TestWhile; end;
--6:用更新游标来为雇员加佣金:(用if实现,创建一个与emp表一摸一样的emp1表,对emp1表进行修改操作),并将更新前后的数据输出出来 create table emp1 as select * from emp; declare cursor csr_Update is select * from emp1 for update OF SAL; -- 加行共享锁 empInfo csr_Update%rowtype; saleInfo emp1.SAL%TYPE; begin FOR empInfo IN csr_Update LOOP IF empInfo.SAL<1500 THEN saleInfo:=empInfo.SAL*1.2; elsif empInfo.SAL<2000 THEN saleInfo:=empInfo.SAL*1.5; elsif empInfo.SAL<3000 THEN saleInfo:=empInfo.SAL*2; END IF; UPDATE emp1 SET SAL=saleInfo WHERE CURRENT OF csr_Update; END LOOP; END;
--9:(知识点:计数器控制游标只提取两条数据;) declare cursor crs_testComput is select * from test order by id asc; --计数器 top_two number:=2; r_testComput crs_testComput%rowtype; begin open crs_testComput; while top_two>0 loop dbms_output.put_line('员工姓名:'||r_testComput.NAME||' 工作时间:'||r_testComput.pid); --计速器减一 top_two:=top_two-1; FETCH crs_testComput INTO r_testComput; end loop; close crs_testComput; end;
create or replace procedure myprocedure is CURSOR CUR_TEST IS --声明显式游标 SELECT ECODE,ENAME FROM EMP; CUR CUR_TEST%ROWTYPE; --定义游标变量,该变量的类型为基于游标C_EMP的记录 BEGIN --For 循环 FOR CUR IN CUR_TEST LOOP --循环体 DBMS_OUTPUT.PUT_LINE('员工编号:'||CUR.ECODE ||'员工姓名:'|| CUR.ENAME); END LOOP; --Fetch 循环 OPEN CUR_TEST;--必须要明确的打开和关闭游标 LOOP FETCH CUR_TEST INTO CUR; EXIT WHEN CUR_TEST%NOTFOUND; --循环体 DBMS_OUTPUT.PUT_LINE('员工编号:'||CUR.ECODE ||'员工姓名:'|| CUR.ENAME); END LOOP; CLOSE CUR_TEST; --While 循环 OPEN CUR_TEST;--必须要明确的打开和关闭游标 FETCH CUR_TEST INTO CUR; WHILE CUR_TEST%FOUND LOOP --循环体 DBMS_OUTPUT.PUT_LINE('员工编号:'||CUR.ECODE ||'员工姓名:'|| CUR.ENAME); FETCH CUR_TEST INTO CUR; END LOOP; CLOSE CUR_TEST; END myprocedure;
使用For循环的有什么好处?
从代码中可以很明显的看出:
- 使用for循环不需要关注游标是否打开或关闭。
- for循环会自动将数据fetch到记录型变量。
- for循环不需要关注何时要退出,也就是不需要写退出满足条件。遍历完成就会退出。
原文:https://www.cnblogs.com/sc-xx/archive/2011/12/03/2275084.html
原文:https://blog.csdn.net/wohaqiyi/article/details/81631257