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数据库最早的版本中是有存储过程和存储函数的区别。如果新版本不支持存储函数,那么老的数据库中若存在存储函数就可能运行出错。

  • 相关阅读:
    一套代码小程序&Web&Native运行的探索05——snabbdom
    一套代码小程序&Web&Native运行的探索04——数据更新
    一套代码小程序&Web&Native运行的探索03——处理模板及属性
    一套代码小程序&Web&Native运行的探索02
    微信小程序开发07-列表页面怎么做
    微信小程序开发06-一个业务页面的完成
    微信小程序开发05-日历组件的实现
    微信小程序开发04-打造自己的UI库
    微信小程序开发03-这是一个组件
    30分钟ES6从陌生到熟悉
  • 原文地址:https://www.cnblogs.com/jiliunyongjin/p/8408918.html
Copyright © 2011-2022 走看看