zoukankan      html  css  js  c++  java
  • 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 过程已成功完成。
  • 相关阅读:
    OSI安全体系结构
    PHP 二维数组根据相同的值进行合并
    Java实现 LeetCode 17 电话号码的字母组合
    Java实现 LeetCode 16 最接近的三数之和
    Java实现 LeetCode 16 最接近的三数之和
    Java实现 LeetCode 16 最接近的三数之和
    Java实现 LeetCode 15 三数之和
    Java实现 LeetCode 15 三数之和
    Java实现 LeetCode 15 三数之和
    Java实现 LeetCode 14 最长公共前缀
  • 原文地址:https://www.cnblogs.com/tenWood/p/6629898.html
Copyright © 2011-2022 走看看