zoukankan      html  css  js  c++  java
  • Oracle存储过程和自定义函数笔记

    学习地址:https://www.imooc.com/learn/370

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

    相同点:完成特定功能的程序。
    区别:是否用return语句返回值。

    语法
    create [or replace] procedure 过程名(参数列表)
    as
    plsql程序体


    create or replace procedure sayhelloworld
    as
    --说明部分

    begin
    dbms_output.put_line('Hello World');
    end;


    调用存储过程
    1.exec sayhelloworld();
    2.begin
    sayhelloworld();
    sayhelloworld();
    end;

    1 exec 存储过程名();2 begin 存储过程名();end /


    创建带参数的存储过程
    -- 给指定的员工涨100块钱的工资,并且打印涨前后涨后的薪水 eno:员工号
    create or replace procedure raisesalary(eno in number) -- in 这是一个输入参数
    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 ! 也不需要 rollback
    -- 注意:一般不在存储过程或者存储函数中,commit 和 rollback
    -- 打印
    dbms_output.put_line('涨前:'||psal||',涨后:'||(psal+100));
    end;
    /
    -- 调用:
    begin
    raisesalary(7839);
    raisesalary(7566);
    end;
    /

    一般不在存储过程中提交或者回滚,大多时间是在调用一次或者多次的时候提交或者回滚
    ,这样会防止出现意外情况。


    创建存储函数的语法

    示例:根据员工号,查询员工年收入。

    create or replace function queryempincom(eno in numbr)

    return number

    as

    --定义变量保存员工的薪水和奖金

    psal emp.sal%type;

    pcomm emp.comm%type;

    begin

    --得到该员工的月薪和奖金
    select sal,comm into pasl,pcomm from emp where empno=eno;

    --直接返回年收入
    return psal*12+nvl(pcomm,0);

    end;


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


    存储过程可以通过out参数返回值。

    什么时候用存储过程、存储函数?


    一般原则:如果只有一个返回值,用存储函数;否则,用存储过程。


    示例:
    create or replace procedure queryempinfor(eno in number,pename out varchar2,
    psal out number,pjob out varchar2)
    as
    begin
    -- 得到该员工的姓名、月薪和职位
    select ename,sal,empjob into pename,psal,pjob from emp where empno=eno;
    end;

    使用JDBC连接数据库

    public class JDBCUtile{
      private static String driver="orable.jdbc.OracleDriver";
      private static String url="jdbc:oracle:thin:@192.168.56.101:1521:orcl";
      private static String user="scott";
      private static String password="tiger";
      // 注册数据库的驱动
      static{
          try{
             Class.forName(driver);
             // --> DriverManager.registerDriver(driver);
          }catch(ClassNotFoundException e){
             throw new ExceptionInInitializerError(e);
          }
      }  // 获取数据库连接
      public static Connection getConnection(){
          try{ 
             return DriverManager.getConnection(url,user,password);
          }catch(SQLException e){e.printStackTrace(); }
             return null;
      }
    
    // 释放数据库的资源
      public static void release(Connection conn,Statement st,ResultSet rs){
        if(rs != null){try{ rs.close();}catch(SQLException e){e.printStackTrace();}finally{rs=null;}}
        if(st != null){try{st.close();}catch(SQLException e){e.printStackTrace();}finally{st=null;}}
        if(conn != null){try{conn.close();}catch(SQLException e){e.printStackTrace();}finally{conn=null;}}
        }
    }

    在应用程序中访问存储过程和存储函数

    使用CallachleStatement接口

    public void testProcedure(){
    //{call <procedure-name>[(<arg1>,<arg2>,...)]}
    String sql="call queryempinform(?,?,?,?)";
    Connection conn=null;
    CallableStatement call=null;
    try{
    // 得到一个连接
    conn=JDBCUtils.getConnection();
    // 通过连接创建出statement
    call=conn.prepareCall(sql);
    // 对于in参数,需赋值,对于out参数,需要申明
    call.setInt(1, 7839); // 设置第一个?为 7839
    call.registerOutParameter(2, OracleTypes.VARCHAR);
    call.registerOutParameter(3, OracleTypes.NUMBER);
    call.registerOutParameter(4, OracleTypes.VARCHAR);
    // 执行调用
    call.execute();
    // 取出结果
    String name=call.getString(2);
    double sal=call.getDouble(3);
    String job=call.getString(4);
    System.out.println(name+"	"+sal+"	"+job);
    }catch(Exception e){
    e.printStackTrace();
    }finally{
    JDBCUtils.release(conn,call,null);
    }
    }

     在out参数中使用光标:

    包头:
    CREATE OR REPLACE PACKAGE MYPACKAGE AS 
        type empcursor is ref cursor;
        procedure queryEmpList(dno in number,empList out empcursor);
    END MYPACKAGE;
    包体(需要实现包头中声明的所有方法,包括存储函数、存储方法):
    CREATE OR REPLACE PACKAGE BODY MYPACKAGE AS
       procedure queryEmpList(dno in number,empList out empcursor) AS
       BEGIN
         --打开光标
          open empList for select * from emp where deptno=dno;
       END queryEmpList;
    END MYPACKAGE;  
    -- 使用desc查看程序包的结构
     desc MYPACKAGE

    所有存储函数的功能都可以有存储过程来代替,为什么在oracle数据库中依然保留存储函数?
    原因:数据库版本升级所造成,版本升级最基本的要求就是要向前向下兼容,在oracle数据库最早的版本中是有存储过程和存储函数的区别。如果新版本不支持存储函数,那么老的数据库中若存在存储函数就可能运行出错。

  • 相关阅读:
    27 Spring Cloud Feign整合Hystrix实现容错处理
    26 Spring Cloud使用Hystrix实现容错处理
    25 Spring Cloud Hystrix缓存与合并请求
    24 Spring Cloud Hystrix资源隔离策略(线程、信号量)
    23 Spring Cloud Hystrix(熔断器)介绍及使用
    22 Spring Cloud Feign的自定义配置及使用
    21 Spring Cloud使用Feign调用服务接口
    20 Spring Cloud Ribbon配置详解
    19 Spring Cloud Ribbon自定义负载均衡策略
    18 Spring Cloud Ribbon负载均衡策略介绍
  • 原文地址:https://www.cnblogs.com/jiliunyongjin/p/8408918.html
Copyright © 2011-2022 走看看