zoukankan      html  css  js  c++  java
  • 游标,存储过程

    1.1什么是游标

    用于临时存储一个查询返回的多行数据(结果集,类似于java的jdbc连接返回的ResultSet集合),通过遍历游标,可以逐行访问处理该结果集的数据.

    游标的使用方式:  声明---打开--读取---关闭

    1.2语法

    游标声明:

    CURSOR 游标名(参数列表)  IS 查询语句;

    游标的打开:

    OPEN 游标名

    游标的取值:

    FETCH 游标名 INTO 变量列表

    游标的关闭:

    CLOSE 游标名

    1.3游标的属性

    游标的属性 返回值类型 说明
    %ROWCOUNT 整型 获取FETCH语句返回的数据行数
    %FOUND 布尔型 最近的FETCH语句返回一行数据则为真,否则为加
    %NOTFOUND 布尔型 与%FOUND属性返回值相反
    %ISOPEN 布尔型 游标已经打开时值为真,否则为假

    其中%NOTFOUND是在游标中找不到元素的时候返回TRUE,通常用来判断退出循环

    1.4创建和使用

    示例:使用游标查询emp表中的所有员工的姓名和工资,并将其依次打印出来

    -- 使用游标查询emp表中的所有员工的姓名和工资,并将其依次打印出来
    declare 
      -- 声明游标 CURSOR 游标名(参数列表)  IS 查询语句;
      CURSOR c_emp IS select ename,sal FROM emp;
      --声明变量接收游标中的数据
      v_ename emp.ename%TYPE;
      v_sal    emp.sal%TYPE;
    begin
      -- 打开游标
      OPEN c_emp;
      
      --遍历游标
      LOOP
        --获取游标中的数据   如果有的话赋值给变量
        FETCH c_emp INTO v_ename,v_sal;
        
        EXIT WHEN c_emp%NOTFOUND;
        dbms_output.put_line('姓名:'||v_ename||',薪水:'||v_sal);
      END LOOP;
      --关闭游标
      CLOSE c_emp;
      
    end;
    

      

    1.5带参数的游标

    示例:使用游标查询并打印某部门的员工的姓名和薪资,部门编号为运行时手动输入.

    -- 使用游标查询并打印某部门的员工的姓名和薪资,部门编号为运行时手动输入.
    declare 
      -- 声明游标 CURSOR 游标名(参数列表)  IS 查询语句;
      CURSOR c_emp(v_deptno emp.deptno%TYPE) IS
       select ename,sal FROM emp where deptno=v_deptno;
      --声明变量接收游标中的数据
      v_ename emp.ename%TYPE;
      v_sal    emp.sal%TYPE;
    begin
      -- 打开游标
      OPEN c_emp(20);
      
      --遍历游标
      LOOP
        --获取游标中的数据   如果有的话赋值给变量
        FETCH c_emp INTO v_ename,v_sal;
        
        EXIT WHEN c_emp%NOTFOUND;
        dbms_output.put_line('姓名:'||v_ename||',薪水:'||v_sal);
      END LOOP;
      --关闭游标
      CLOSE c_emp;
      
    end;
    

     给对应级别的员工涨工资,key是empno

     

    -- 给对应级别的员工涨工资,key是empno 
    declare 
      -- 声明光标
      cursor cemp is
       select empno,job from emp;
       --声明变量接收光标数据
       pempno emp.empno%TYPE;
       pempjob emp.job%TYPE;
    begin
      -- 事务回滚
      rollback;
      --打开光标
      open cemp;
      loop
        --遍历光标取出一个员工
        fetch cemp into pempno,pempjob;
        --退出条件
        exit when cemp%notfound;
        --判断员工的职位
        if pempjob='PRESIDENT' then update emp set sal=sal+1000 where empno=pempno;
         -- if condition then block ;elsif condition then block;else block;end if;
         elsif pempjob='MANAGER' then update emp set sal=sal+800 where empno=pempno;
         else update emp set sal=sal+400 where empno=pempno;
         end if;
    
        end loop;
      --关闭光标
      close cemp;
      -- oracle的默认事务隔离级别是read committed
       --事务的ACID 原子性、一致性、隔离性、持久性
     commit;
    
    end;
    

    存储过程和存储函数

    数据库存储过程:指存储在数据库中供所有用户程序调用的子程序叫存储过程、存储函数

    ·相同点:完成特定功能的程序
    ·不同点:是否用return语句返回值。存储函数可以return返回值。存储过程不可以通过return语句返回函数值。

    1.创建存储过程

    create or replace procedure 过程名(参数列表)
    as
    begin
    ..........PLSQL子程序体;
    end;

    2.执行存储过程

    --1.exec 存储过程名();
    --2.begin
         存储过程名();
        end;
    带参数的存储过程
     举例:为指定的员工,涨100块钱的工资;并且打印涨前和涨后的薪水
    1、创建一个带参数的存储过程:
     给执行的员工涨100块钱的工资,并且打印涨前和涨后的薪水
    
    create or replace procedure raisesalary(eno in number)
    as
    --定义一个变量保存涨前的薪水
     psal emp.sal%TYPE;
     begin
       --得到员工涨前的薪水
       select sal into psal from emp where empno=eno;
       --给员工涨100
       update emp set sal=sal+100 where empno=eno
       --需不需要commit?
       --注意:一般不在存储过程或存储函数中,commit和rollback
       --打印
       dbms_output.put_line('涨前:'||psal||'涨后:'(pasl+100))
     end;
    --2、如何调用:
     begin
      raisesalary(7839);
      raisesalary(7566);
     commit;
     end;
    

    存储过程的调试

    1.调试存储过程最好放到Oracle数据库所在的系统或虚拟机上,解压SQL developer ,双击运行。
    2.为了确保存储过程或函数是可调试的,右键“以编译并进行调试”,点击红色按钮“调试”
    3.利用已写好的调用函数进行调试。

    1.函数的定义

      是一个命名的存储程序,可带参数,并返回一个计算值。必须有return 子句,用于返回函数值。

    2.创建存储函数语法

      create or replace function 函数名(参数列表)
      return 函数值类型
      as
      begin
        PLSQL子程序体;
      end;

    3.表达式中某个字段为空时,表达式返回值为空。为防止含有表达式的返回值错误,在可能为空的字段上加上NVL(字段名,0)。

    --查询某个员工的年收入

     

    create or replace function queryemp_income(eno number) return number
    as 
        --定义变量接收薪水和奖金
        p_sal emp.sal%type;
        p_comm emp.comm%type;
    begin
    
      select sal,comm into p_sal,p_comm from emp where empno=eno;
      --nvl为遇空函数,如果p_comm为空则返回0
      return nvl(p_comm,0)+p_sal*12;
    end;
    

    1.存储过程和存储函数的区别

      存储函数可以有一个返回值,存储过程没有返回值

    2.in out 参数

      存过和函数都可以通过out 指定一个或多个输出参数。可以利用out参数,实现多个返回值。

    3.使用存过和存储函数的原则

      只有一个返回值的话,用存储函数;否则,用存储过程。

     

    create or replace procedure query
    (eno in number,
     pename out varchar2,
    psal out  number,
    pjob out varchar2
     )
    as
    begin
    select ename,sal,job into pename,psal,pjob from emp where  empno=eno;
    end;
    

      

     

     

     

  • 相关阅读:
    各种文件的mime类型
    LeetCode_122. Best Time to Buy and Sell Stock II
    LeetCode_121. Best Time to Buy and Sell Stock
    LeetCode_119. Pascal's Triangle II
    LeetCode_118. Pascal's Triangle
    LeetCode_112. Path Sum
    LeetCode_111. Minimum Depth of Binary Tree
    LeetCode_110. Balanced Binary Tree
    LeetCode_108. Convert Sorted Array to Binary Search Tree
    LeetCode_107. Binary Tree Level Order Traversal II
  • 原文地址:https://www.cnblogs.com/tanlei-sxs/p/9807982.html
Copyright © 2011-2022 走看看