PL/SQL developer基础语法学习(三)之游标

一、游标分为:隐式游标和显示游标

1.隐式游标:发生与操作的DML语句中 sql游标

例子(实例中的表都是使用的oracle中的初始表):

declare
     --拷贝emp的结构+记录
     v_sql varchar2(100) :='create table emp_copy2 as select * from emp where 1=1';
     --更新记录
     v_update_sql varchar2(100) :='update emp_copy2 set sal =sal+1000 where empno=&empno';
begin
     --创建表 (存在记录的cud 就存在sql游标)
     execute immediate v_sql;
     dbms_output.put_line('更新了'||sql%rowcount||'条记录');     
     --更新记录  (隐式存在SQL游标)
     execute immediate v_update_sql;
     dbms_output.put_line('更新了'||sql%rowcount||'条记录');     
     commit;
     --查看状态
     if not sql%isopen then
         dbms_output.put_line('隐式游标自动关闭');
     end if;
         --删除表
     execute immediate 'drop table emp_copy2 cascade constraints';     

exception 
   when  no_data_found then
        dbms_output.put_line('数据未找到'||sqlcode||'-->'||sqlerrm);  
        rollback;
   when too_many_rows then
        dbms_output.put_line('数据超出'||sqlcode||'-->'||sqlerrm);  
         rollback;
   when others then
        dbms_output.put_line('其他异常'||sqlcode||'-->'||sqlerrm);  
         rollback;
end;

2.显示游标:可分为静态游标和动态游标(ref游标)

(1)静态游标:可分为有参和无参

1)实例(无参)

declare 
      --创建并声明
      cursor  cur_emp is select ename,sal,dname,loc from emp_copy e  join dept d  on e.deptno=d.deptno where e.deptno=20;
begin 
      --不用打开 不用声明变量  不用抓取 不用关闭
      for v_emp in cur_emp loop
          dbms_output.put_line(v_emp.ename||'-->'||v_emp.sal||'-->'||v_emp.dname||'-->'||v_emp.loc);
      end loop;

exception 
   when  no_data_found then
        dbms_output.put_line('数据未找到'||sqlcode||'-->'||sqlerrm);  
        rollback;
   when too_many_rows then
        dbms_output.put_line('数据超出'||sqlcode||'-->'||sqlerrm);  
         rollback;
   when others then
        dbms_output.put_line('其他异常'||sqlcode||'-->'||sqlerrm);  
         rollback;
end;

2)实例(有参):

declare 
      --创建并声明
      cursor  cur_emp(v_deptno dept.deptno%type) is select ename,sal,dname,loc from emp_copy e  join dept d  on e.deptno=d.deptno where e.deptno=v_deptno;
begin 
      --不用打开 不用声明变量  不用抓取 不用关闭
      for v_emp in cur_emp(&部门编号) loop
          dbms_output.put_line(v_emp.ename||'-->'||v_emp.sal||'-->'||v_emp.dname||'-->'||v_emp.loc);
      end loop;

exception 
   when  no_data_found then
        dbms_output.put_line('数据未找到'||sqlcode||'-->'||sqlerrm);  
        rollback;
   when too_many_rows then
        dbms_output.put_line('数据超出'||sqlcode||'-->'||sqlerrm);  
         rollback;
   when others then
        dbms_output.put_line('其他异常'||sqlcode||'-->'||sqlerrm);  
         rollback;
end;

3)更新(操作数据)
更新(update和delete)游标 :
a)、游标声明时加入: for update
b)、操作记录指向当前行: where current of 游标
实例:

--更新游标操作
declare 
      --创建并声明
      cursor  cur_emp(v_deptno emp.deptno%type) is select * from emp_copy e where e.deptno=v_deptno for update;
begin 
      --不用打开 不用声明变量  不用抓取 不用关闭
      for v_emp in cur_emp(&部门编号) loop
         update emp_copy set sal=sal+500 where current of cur_emp;
      end loop;
      commit;
exception 
   when  no_data_found then
        dbms_output.put_line('数据未找到'||sqlcode||'-->'||sqlerrm);  
        rollback;
   when too_many_rows then
        dbms_output.put_line('数据超出'||sqlcode||'-->'||sqlerrm);  
         rollback;
   when others then
        dbms_output.put_line('其他异常'||sqlcode||'-->'||sqlerrm);  
         rollback;
end;

(2).动态游标ref:又分为强类型和弱类型
动态游标: 在使用过程中,动态关联结果集

1.弱类型和强类型的区别:
弱类型: 随意关联结果集
强类型: 同一个范围内的 结果集

实例(弱类型)

declare 
    --1、创建游标类型
    type ref_emp is ref cursor;
    --2、声明变量
    v_cur_emp ref_emp;  

    v_emp emp%rowtype;
    v_dept dept%rowtype;

    v_flag number(5) :=&选择请输入10;
begin 
    if  v_flag=1 then
       --3、打开游标  关联结果集
        open v_cur_emp for select * from emp where sal>1000;
       --4、操作
       loop
             fetch v_cur_emp into v_emp;
             exit when v_cur_emp%notfound;
             dbms_output.put_line(v_emp.ename);
       end loop;   
   else    
       --再次使用游标
       open v_cur_emp for select * from dept;
        --4、操作
       loop
             fetch v_cur_emp into v_dept;
             exit when v_cur_emp%notfound;
             dbms_output.put_line(v_dept.dname);
       end loop;   
   end if;
   --5、关闭游标
   close v_cur_emp;   

exception 
   when  no_data_found then
        dbms_output.put_line('数据未找到'||sqlcode||'-->'||sqlerrm);  
        rollback;
   when too_many_rows then
        dbms_output.put_line('数据超出'||sqlcode||'-->'||sqlerrm);  
         rollback;
   when others then
        dbms_output.put_line('其他异常'||sqlcode||'-->'||sqlerrm);  
         rollback;
end;

实例(强类型)

declare 
    --1、创建强类型ref游标
    type ref_emp is ref cursor return emp%rowtype;
    --2、声明变量
    v_cur_emp ref_emp;  

    v_emp emp%rowtype;   
    v_flag number(5) :=&选择请输入10;
begin 
    if  v_flag=1 then
       --3、打开游标  关联结果集
        open v_cur_emp for select * from emp where sal>3000;
         dbms_output.put_line('--------工资大于3000的员工名称----------');      
   else    
       --再次使用游标 (同类型结果集)
       open v_cur_emp for select * from emp where comm is not null;  
       dbms_output.put_line('--------存在佣金的员工名称----------');         
   end if;

    --4、操作
     loop
           fetch v_cur_emp into v_emp;
           exit when v_cur_emp%notfound;
           dbms_output.put_line(v_emp.ename||'-->'||v_emp.comm);
     end loop;   
   --5、关闭游标
   close v_cur_emp;   

exception 
   when  no_data_found then
        dbms_output.put_line('数据未找到'||sqlcode||'-->'||sqlerrm);  
        rollback;
   when too_many_rows then
        dbms_output.put_line('数据超出'||sqlcode||'-->'||sqlerrm);  
         rollback;
   when others then
        dbms_output.put_line('其他异常'||sqlcode||'-->'||sqlerrm);  
         rollback;
end;

静态游标和动态游标的区别:
1、 不是创建时关联结果集,打开时关联结果集 。不能使用for
2、 先创建游标类型 再声明游标变量。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章