oracle游标使用的几个场景

- 声明游标;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循环的有什么好处?

  从代码中可以很明显的看出:

  1. 使用for循环不需要关注游标是否打开或关闭。
  2. for循环会自动将数据fetch到记录型变量。
  3. for循环不需要关注何时要退出,也就是不需要写退出满足条件。遍历完成就会退出。

 原文:https://www.cnblogs.com/sc-xx/archive/2011/12/03/2275084.html

原文:https://blog.csdn.net/wohaqiyi/article/details/81631257

原文地址:https://www.cnblogs.com/thomasbc/p/15655288.html