zoukankan      html  css  js  c++  java
  • PL/SQL游标

    1. 显示游标
    --显示游标的定义
    declare
       --定义一个显示游标,并确定内容是什么,cursor... is select....from....
      cursor c_emp is select empno,ename,job,mgr,hiredate,sal,comm,deptno from emp;
       ---定义一个行对象
       r_emp emp%rowtype;
       --这里定义的式行列式,所以就需要在定义游标的时候取出emp的所有字段,
       --并且顺序还要按照emp的顺序来取
    begin
       --操作游标步骤
       --打开游标
       open c_emp;
          --使用循环抓取游标中的所有数据
          loop
            --抓取数据放入变量或行对象中
            fetch c_emp into r_emp;
            --这里不需要from语句
            ---抓取数据的循环终止条件
            exit when c_emp%notfound;
            ---取出行对象的每一个字段,抓取一条数据就打印出来
            dbms_output.put_line('姓名:'||r_emp.ename||',员工编号:'||r_emp.empno);    
          end loop;
       --关闭游标
       close c_emp;
    end;
    
    1. 输入部门编号,查询视图v_emp_dept表的部门名称和员工名称
      我们通过一个例题来加深对显示游标的理解
      这里我们先创建一个视图
    create or replace view v_emp_dept as select emp.deptno,dname,ename from emp join dept on dept.deptno=emp.deptno;--->这里创建视图的时候我们添加一个or replace 可以多次执行该语句
    

    这里写图片描述
    那么这个视图我们就创建好了
    下面我们就需要通过用户输入一个部门编号,然后我们返回出查询的结果

    
    ---利用游标查询,先将SQL语句查询的结果放在游标里面,再 利用循环将查询结果输出
    declare
       cursor c_emp_dept is 
          select ename,dname from v_emp_dept where deptno='&请输入部门编号:';
           --->cursor 相当于存储了我们需要查询的所有信息,也就是我们将查询的SQL表放在了cursor里面,并且记得游标的声明是放在declare语句里面的
       e_name v_emp_dept.ename%type;
       d_name v_emp_dept.dname%type;   
    begin
       open c_emp_dept;--->一旦定义了游标就要记得先把打开游标和关闭游标写好
         --这里需要先取出一条数据再进入while循环
         fetch c_emp_dept into e_name,d_name;
         --while ....loop.....end loop ==while() do......
         while c_emp_dept%found loop
            --取出一条数据就打印出来,然后再继续取,直到c_emp_dept%nofound就跳出循环
            dbms_output.put_line('当前的行数:'||c_emp_dept%rowcount||',员工名称:'||e_name||',部门名称:'||d_name);
            fetch c_emp_dept into e_name,d_name;
         end loop;    
       close c_emp_dept;
    end;
    
    ----使用for循环遍历存储有查询结果的游标,并且输出
    declare
      cursor c_cursor is 
         select ename,dname from v_emp_dept where  deptno='&请输入部门编号:';
    begin
      ---使用for each 遍历游标的好处是不用再重新定义一个行对象或者字段对象来通过抓取游标中的字段进行存储
      --这里的i就相当于一张表,和游标一模一样,可以直接通过i来获取表中的字段,并且也没有了while之类的循环的
      --终止条件
      for i in c_cursor loop
         dbms_output.put_line('员工名称:'||i.ename||',部门名称:'||i.dname);
      end loop;   
    end;
    ----遍历显示游标的循环有while循环和for循环,以后我们一般都采用for循环
    1. –隐示游标
      –隐示没有声明,打开,关闭操作,
      –隐示游标是由系统自动产生,名字统一叫做SQL(每执行一个DML语句就会产生一个隐示游标)
      –在隐示游标中可以使用三个属性
      –%NOTFOUND
      –%FOUND
      –%ROWCOUNT

    2. 写一个PL/SQL块,插入表employee中100条数据。插入该表中字段id用序列seq_employee实现,薪水和姓名字段可以任意填写。

    
    --.写一个PL/SQL块,插入表employee中100条数据。
    --插入该表中字段id用序列seq_employee实现,薪水和姓名字段可以任意填写。
    create table t_employee (
         e_id number primary key,
         e_name varchar2(25),
         e_sal number(7,2)
    );
    select * from t_employee;
    --使用序列sequence之前必须要先创建一个序列
    create sequence seq_employee;
    --使用PL/SQL块循环插入数据
    --注意这里使用的for循环和遍历游标的for循环不一样
    --这里的for循环是for i in start..end loop....end loop
    --这里的i就是一个迭代器的变量值
    --而遍历表或者游标的时候for i in c_cursor loop...end loop;
    --这里的i代指的就是一张表本身,或者游标本身
    declare 
    begin
      for i in 1..100 loop
        insert into t_employee values(seq_employee.nextval,'wang'||i,i*500);
        commit;---凡是不是查询的语句最好都要设置为自动提交,防止死锁
      end loop;
    end;
    select * from t_employee;
    

    那么我们可以看下插入数据之后的表
    这里写图片描述

    1. –.写一个语句块,在语句块中定义一个显式游标,按id升序排列,打印表emp中前十条数据。
    declare
      --定义一个游标把查询语句返回出来的表存储起来
      cursor c_mycur is 
         select e_id,e_name,e_sal from t_employee where rownum<=10 ;
    begin
      --接下来的任务就是将游标中的表利用循环打印出来
      --这里我们利用for循环来遍历游标
      for i in c_mycur loop
        dbms_output.put_line('编号'||i.e_id||',姓名:'||i.e_name||',薪水:'||i.e_sal);   
      end loop;
    end;
    1. 创建存储过程pro_emp,输入员工薪水范围,返回员工工号、姓名、薪水结果集,结果集按员工薪水升序排列。
    --对于参数记得定义类型,这里是形参,不用定义长度,不然会报错
    --定义存储过程和定义视图一样都可以加上or replace 以免重复执行该语句会报错
    --创建存储过程同样需要PL/SQL语句块不过不需要声明的部分,只需要begin...end pro_xx;
    --一定记得结束的时候要写存储过程的名字
    --对于存储过程传递的形参,传入不需要写in,但是输出的参数需要再参数名和类型名之间添加out
    
    --存储过程的定义
    create or replace procedure pro_emp (min_sal number ,max_sal number , sal_result out sys_refcursor)is---->这里定义输出参数为一个引用型的游标
    begin 
      open sal_result for select e_id,e_name,e_sal from t_employee 
      where e_sal between min_sal and max_sal;---->要向引用型的游标中添加数据需要先打开游标然后利用for 赋值给游标
    end pro_emp;
    
      --存储过程的调用
    declare
    sal_result sys_refcursor;--由于存储过程里面有引用型的变量,
    --所以这里的实参也需要声明一个引用型的游标,引用型的游标声明的时候直接定义类型就行了
    --不用像显示游标采用cursor c_cursor is select  from 
    e_row t_employee%rowtype;---不能用for each 就只能通过行对象来存储游标取出来的字段
    begin
      pro_emp(2000,5000,sal_result);
      --for i in sal_result loop
      --使用引用游标的时候就不能使用for each进行遍历了
      loop
        fetch sal_result into e_row;
        exit when sal_result%notfound;
       dbms_output.put_line('编号:'||e_row.e_id||',姓名:'||e_row.e_name||',工资:'||e_row.e_sal);
      end loop;
    end;
    欢迎关注我的公众号:小秋的博客 CSDN博客:https://blog.csdn.net/xiaoqiu_cr github:https://github.com/crr121 联系邮箱:rongchen633@gmail.com 有什么问题可以给我留言噢~
  • 相关阅读:
    UVA 254 Towers of Hanoi
    UVA 701 The Archeologists' Dilemma
    UVA 185 Roman Numerals
    UVA 10994 Simple Addition
    UVA 10570 Meeting with Aliens
    UVA 306 Cipher
    UVA 10160 Servicing Stations
    UVA 317 Hexagon
    UVA 10123 No Tipping
    UVA 696 How Many Knights
  • 原文地址:https://www.cnblogs.com/flyingcr/p/10428321.html
Copyright © 2011-2022 走看看