• orace学习操作(4)


    Orace游标:

    一、游标简介:                                      

    使用游标,我们可以对具体操作数据,比如查询的结果,对行,列数据进行更加细致的处理。以及对其他DML操作进行判断等操作;

    二、显示游标:                                        

    1.静态的指定变量类型:

    SQL> declare cursor cu_emp is select empno,ename,sal from emp;
      2  e_no number;
      3  e_name varchar2(10);
      4  e_sal number;
      5  begin
      6     open cu_emp;
      7     fetch cu_emp into e_no, e_name, e_sal;
      8     while cu_emp%found loop
      9             dbms_output.put_line('编号:'||e_no||',姓名:'||e_name||',基本薪资:'||e_sal);
     10     fetch cu_emp into e_no, e_name, e_sal;
     11     end loop;
     12     close cu_emp;
     13  end;
     14  /
    编号:7369,姓名:SMITH,基本薪资:800
    编号:7499,姓名:ALLEN,基本薪资:1600
    编号:7521,姓名:WARD,基本薪资:1250
    编号:7566,姓名:JONES,基本薪资:2975
    编号:7654,姓名:MARTIN,基本薪资:1250
    编号:7698,姓名:BLAKE,基本薪资:2850
    编号:7782,姓名:CLARK,基本薪资:2450
    编号:7788,姓名:SCOTT,基本薪资:3000
    编号:7839,姓名:KING,基本薪资:5000
    编号:7844,姓名:TURNER,基本薪资:1500
    编号:7876,姓名:ADAMS,基本薪资:1100
    编号:7900,姓名:JAMES,基本薪资:950
    编号:7902,姓名:FORD,基本薪资:3000
    编号:7934,姓名:MILLER,基本薪资:1300
    
    PL/SQL 过程已成功完成。

    2.动态指定变量类型:

    SQL> declare cursor cu_emp is select empno,ename,sal from emp;
      2  e_no emp.empno%type;
      3  e_name emp.ename%type;
      4  e_sal emp.sal%type;
      5  begin
      6     open cu_emp;
      7     fetch cu_emp into e_no, e_name, e_sal;
      8     while cu_emp%found loop
      9             dbms_output.put_line('编号:'||e_no||',姓名:'||e_name||',基本薪资:'||e_sal);
     10     fetch cu_emp into e_no, e_name, e_sal;
     11     end loop;
     12     close cu_emp;
     13  end;
     14  /
    编号:7369,姓名:SMITH,基本薪资:800
    编号:7499,姓名:ALLEN,基本薪资:1600
    编号:7521,姓名:WARD,基本薪资:1250
    编号:7566,姓名:JONES,基本薪资:2975
    编号:7654,姓名:MARTIN,基本薪资:1250
    编号:7698,姓名:BLAKE,基本薪资:2850
    编号:7782,姓名:CLARK,基本薪资:2450
    编号:7788,姓名:SCOTT,基本薪资:3000
    编号:7839,姓名:KING,基本薪资:5000
    编号:7844,姓名:TURNER,基本薪资:1500
    编号:7876,姓名:ADAMS,基本薪资:1100
    编号:7900,姓名:JAMES,基本薪资:950
    编号:7902,姓名:FORD,基本薪资:3000
    编号:7934,姓名:MILLER,基本薪资:1300
    
    PL/SQL 过程已成功完成。

    3.行类型:%rowtype:

    SQL> declare cursor cu_emp is select * from emp;
      2  e emp%rowtype;
      3  begin
      4     open cu_emp;
      5     fetch cu_emp into e;
      6     while cu_emp%found loop
      7             dbms_output.put_line('编号:'||e.empno||',姓名:'||e.ename||',基本薪资:'||e.sal);
      8     fetch cu_emp into e;
      9     end loop;
     10     close cu_emp;
     11  end;
     12  /
    编号:7369,姓名:SMITH,基本薪资:800
    编号:7499,姓名:ALLEN,基本薪资:1600
    编号:7521,姓名:WARD,基本薪资:1250
    编号:7566,姓名:JONES,基本薪资:2975
    编号:7654,姓名:MARTIN,基本薪资:1250
    编号:7698,姓名:BLAKE,基本薪资:2850
    编号:7782,姓名:CLARK,基本薪资:2450
    编号:7788,姓名:SCOTT,基本薪资:3000
    编号:7839,姓名:KING,基本薪资:5000
    编号:7844,姓名:TURNER,基本薪资:1500
    编号:7876,姓名:ADAMS,基本薪资:1100
    编号:7900,姓名:JAMES,基本薪资:950
    编号:7902,姓名:FORD,基本薪资:3000
    编号:7934,姓名:MILLER,基本薪资:1300
    
    PL/SQL 过程已成功完成。

    上面的也可以查询带条件:

    SQL> declare cursor cu_emp is select * from emp where sal > 2000 and sal < 3000;
    
      2  e emp%rowtype;
      3  begin
      4     open cu_emp;
      5     fetch cu_emp into e;
      6     while cu_emp%found loop
      7             dbms_output.put_line('编号:'||e.empno||',姓名:'||e.ename||',
    基本薪资:'||e.sal);
      8     fetch cu_emp into e;
      9     end loop;
     10     close cu_emp;
     11  end;
     12  /
    编号:7566,姓名:JONES,基本薪资:2975
    编号:7698,姓名:BLAKE,基本薪资:2850
    编号:7782,姓名:CLARK,基本薪资:2450
    
    PL/SQL 过程已成功完成。
    View Code

    4.游标的其他循环方式:

    SQL> declare cursor c is select * from emp;
      2  v_emp c%rowtype;
      3  begin
      4     open c;
      5          fetch c into v_emp;
      6          dbms_output.put_line(v_emp.ename);
      7     close c;
      8  end;
      9  /
    SMITH
    
    PL/SQL 过程已成功完成。

    //cursor c is xx 声明一个游标,但是并不会真真正正的从数据库取数据,open c才取数据
    //fetch c 拿出第一个数据,并且游标指向下一行数据;fetch开始是指在第一条数据上,每fetch下,就指向下一条;

    loop循环:

    SQL> declare cursor c is select * from emp;
      2  v_emp c%rowtype;
      3  begin
      4     open c;
      5             loop
      6                     fetch c into v_emp;
      7                     exit when(c%notfound);
      8                     dbms_output.put_line(v_emp.ename);
      9             end loop;
     10     close c;
     11  end;
     12  /
    SMITH
    ALLEN
    WARD
    ...
    PL/SQL 过程已成功完成。

    while循环:

    SQL> declare cursor c is select * from emp;
      2  v_emp c%rowtype;
      3  begin
      4     open c;
      5     fetch c into v_emp;
      6     while(c%found) loop
      7             dbms_output.put_line(v_emp.ename);
      8             fetch c into v_emp;
      9     end loop;
     10     close c;
     11  end;
     12  /
    SMITH
    ALLEN
    ...
    
    PL/SQL 过程已成功完成。
    View Code

    for循环:

    SQL> declare cursor c is select * from emp;
      2  begin
      3     for v_emp in c loop
      4             dbms_output.put_line(v_emp.ename);
      5     end loop;
      6  end;
      7  /
    SMITH
    ALLEN
    ...
    
    PL/SQL 过程已成功完成。
    //不需要声明v_emp,for循环自动声明;
    //不需要open游标、close游标,for循环开始自动打开游标,循环结束自动关闭游标;最不容易出错。使用最多。

    5.带参数的游标:

    SQL> select ename, sal from emp where deptno=30 and job='CLERK';
    
    ENAME             SAL
    ---------- ----------
    JAMES             950
    
    SQL> declare cursor c(v_deptno emp.deptno%type, v_job emp.job%type)
      2             is select ename,sal from emp where deptno = v_deptno and job = v_job;
      3  begin
      4     for v_temp in c(30, 'CLERK') loop
      5             dbms_output.put_line(v_temp.ename);
      6     end loop;
      7  end;
      8  /
    JAMES
    
    PL/SQL 过程已成功完成。

    6.可更新的游标:

    declare cursor c is select * from emp2 for update;
    begin
        for v_temp in c loop
            if(v_temp.sal < 2000) then
                update emp2 set sal = sal*2 where current of c;
            elsif (v_temp.sal = 5000) then
                delete from emp2 where current of c;
            end if;
        end loop;
        commit;
    end;

    三、隐式游标:                                                        

    SQL> begin
      2     if sql%isopen then
      3             dbms_output.put_line('sql游标以打开');
      4     else
      5             dbms_output.put_line('sql游标未打开');
      6     end if;
      7  end;
      8  /
    sql游标未打开
    
    PL/SQL 过程已成功完成。
    SQL> declare e_count number;
      2  begin
      3     select count(*) into e_count from emp;
      4     dbms_output.put_line('游标捕获的记录数:'||sql%rowcount);
      5  end;
      6  /
    游标捕获的记录数:1
    
    PL/SQL 过程已成功完成。

    %rowcount :   新增、修改影响的记录数会返回;

    SQL> begin
      2     update emp2 set sal = 808 where ename='SMITH';
      3     if sql%rowcount=1 then
      4             dbms_output.put_line('已更新');
      5     else
      6             dbms_output.put_line('未更新');
      7     end if;
      8  end;
      9  /
    已更新
    
    PL/SQL 过程已成功完成。
    SQL> begin
      2     update emp2 set sal = 800 where ename='SMITH';
      3     if sql%found then
      4             dbms_output.put_line('已更新');
      5     else
      6             dbms_output.put_line('未更新');
      7     end if;
      8  end;
      9  /
    已更新
    
    PL/SQL 过程已成功完成。
    View Code

    四、动态游标                                              

    前面说的都是静态游标:开始声明就定死了;静态的;

    1.强类型动态游标:

    有个需求,老大(job为PRESIDENT)在的时候打印老大的信息,不然打印emp表的所有信息:

    SQL> declare type emptype is ref cursor return emp%rowtype;
      2  cu_emp emptype;
      3  e_count number;
      4  e emp%rowtype;
      5  begin
      6     select count(*) into e_count from emp where job = 'PRESIDENT';
      7     if e_count=0 then
      8             open cu_emp for select * from emp;
      9     else
     10             open cu_emp for select * from emp where job = 'PRESIDENT';
     11     end if;
     12     fetch cu_emp into e;
     13     while cu_emp%found loop
     14             dbms_output.put_line('编号:'||e.empno||',姓名:'||e.ename||',基本薪资:'||e.sal);
     15             fetch cu_emp into e;
     16     end loop;
     17     close cu_emp;
     18  end;
     19  /
    编号:7839,姓名:KING,基本薪资:5000
    
    PL/SQL 过程已成功完成。

    2.弱类型动态游标:

     需求:老大在的时候,输出老大信息;老大不在的时候,输出薪资等级信息;

    SQL> declare type customType is ref cursor;
      2  e_count number;
      3  e emp%rowtype;
      4  s salgrade%rowType;
      5  cType customType;
      6  begin
      7    select count(*) into e_count from emp where job='PRESIDENT';
      8    if e_count=0 then
      9      open cType for select * from salgrade;
     10      fetch cType into s;
     11      while cType%found loop
     12        dbms_output.put_line('等级:'||s.grade||',最低薪资:'||s.losal||',最高薪资:'||s.hisal);
     13        fetch cType into s;
     14      end loop;
     15      close cType;
     16    else
     17      open cType for select * from emp where job='PRESIDENT';
     18      fetch cType into e;
     19      while cType%found loop
     20        dbms_output.put_line('编号:'||e.empno||',姓名:'||e.ename||',基本薪资:'||e.sal);
     21        fetch cType into e;
     22      end loop;
     23      close cType;
     24    end if;
     25  end;
     26  /
    编号:7839,姓名:KING,基本薪资:5000
    
    PL/SQL 过程已成功完成。
  • 相关阅读:
    别让猴子翻到背上
    python生成二维码
    50条经典爱情观
    智力测试题
    SQL数据库优化
    递归函数实现二分查找法
    软件开发类别
    递归函数的深度问题
    UVALive
    UVALive
  • 原文地址:https://www.cnblogs.com/tenWood/p/6629898.html
Copyright © 2020-2023  润新知