zoukankan      html  css  js  c++  java
  • 【Java EE 学习 29 下】【JDBC编程中操作Oracle数据库】【调用存储过程的方法】

    疑问:怎样判断存储过程执行之后返回值是否为空。

    一、连接oracle数据库

      1.需要的jar包:在安装的oracle中就有,所以不需要到官网下载,我的oracle11g下:D:appkdyzmproduct11.2.0dbhome_1jdbclib,文件夹中有若干.jar文件,选择ojdbc6.jar即可。

      2.连接oracle

        驱动位置:oracle.jdbc.OracleDriver

        url写法:jdbc:oracle:thin:@localhost:1521:orcl

      3.JDBCUtils

    package com.kdyzm.dbutils;
    
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.sql.Statement;
    
    public class JDBCUtils
    {
        private static final String driver="oracle.jdbc.driver.OracleDriver";
        private static final String url="jdbc:oracle:thin:@localhost:1521:orcl";
        private static final String username="scott";
        private static final String password="tiger";
        static
        {
            try {
                Class.forName(driver);
            } catch (ClassNotFoundException e) {
                throw new ExceptionInInitializerError("Oracle数据库连接初始化失败!");
            }
        }
        //获取Connection连接的方法
        public static Connection getConnection()
        {
            Connection conn=null;
            try {
                conn=DriverManager.getConnection(url,username,password);
            } catch (SQLException e) {
                e.printStackTrace();
            }
            return conn;
        }
        
        //释放资源的标准方法
        public static void free(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;
                                }
                            }
                        }
                    }
                }
            }
        }
    }

      4.测试连接

    package com.kdyzm.test;
    
    import java.sql.Connection;
    
    import com.kdyzm.dbutils.JDBCUtils;
    
    /*
     * 测试与Oracle数据库之间的连接
     */
    public class TestConnection {
        public static void main(String[] args) {
            Connection conn=JDBCUtils.getConnection();
            System.out.println(conn);
            JDBCUtils.free(conn, null, null);
        }
    }

    二、调用存储过程

      1.使用CallableStatement标准接口。

        java.sql.Statement

          |--java.sql.CallableStatement

      创建存储过程:

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

      2.调用存储过程

    package com.kdyzm.test;
    /*
     * 测试oracle调用存储过程,并得到返回值。
     */
    import java.sql.CallableStatement;
    import java.sql.Connection;
    import java.sql.ResultSet;
    import oracle.jdbc.OracleTypes;
    import org.junit.Test;
    import com.kdyzm.dbutils.JDBCUtils;
    
    public class TestProcedure {
        @Test
        public void testProcedure()
        {
            Connection conn=null;
            ResultSet rs=null;
            CallableStatement cs=null;
            //SQL语句的形式:{call <procedure-name>[(<arg1>,<arg2>, ...)]}
            String sql="{call searchEmpByEmpno(?,?,?,?)}";//这里的存储过程拥有四个参数,第一个是in类型的,其余的是out类型的。
            try
            {
                conn=JDBCUtils.getConnection();
                cs=conn.prepareCall(sql);            //得到CallableStatement对象
                cs.setInt(1, 7566);                    //设置in值
                
                //注册三个输出值
                cs.registerOutParameter(2, OracleTypes.VARCHAR);
                cs.registerOutParameter(3, OracleTypes.VARCHAR);
                cs.registerOutParameter(4, OracleTypes.DOUBLE);
                //执行存储过程
                cs.execute();
                //得到返回结果
                String ename=cs.getString(2);
                String job=cs.getString(3);
                double sal=cs.getDouble(4);
                System.out.println(ename+" 的工作是: "+job);
                System.out.println(ename+" 的薪水是: "+sal);
            }
            catch(Exception e)
            {
                e.printStackTrace();
            }
            finally{
                JDBCUtils.free(conn, cs, rs);
            }
        }
    }

    三、调用存储函数

      1.本来没有什么不同之处,但这里由于任性使然,故展示一二,创建存储函数

    create or replace function myfun(fempno in number)
    return VARCHAR2
    as
      fename VARCHAR2(20);
    begin
      select ename into fename from emp where empno=fempno;
      return fename;
    end;

      2.调用存储函数

    package com.kdyzm.test;
    
    import java.sql.CallableStatement;
    import java.sql.Connection;
    import java.sql.ResultSet;
    import oracle.jdbc.OracleTypes;
    import com.kdyzm.dbutils.JDBCUtils;
    /*
     *测试调用存储函数。
     */
    public class TestFunction {
        public static void main(String[] args) {
            Connection conn=null;
            ResultSet rs=null;
            CallableStatement cs=null;
    //        {?= call <procedure-name>[(<arg1>,<arg2>, ...)]}
            String sql="{?=call myfun(?)}";
            try
            {
                conn=JDBCUtils.getConnection();
                cs=conn.prepareCall(sql);
                cs.registerOutParameter(1, OracleTypes.VARCHAR);
                cs.setInt(2, 7521);
                cs.execute();
                String ename=cs.getString(1);
                System.out.println("查询结果为:"+ename);
            }
            catch(Exception e)
            {
                e.printStackTrace();
            }
            finally{
                JDBCUtils.free(conn, cs, rs);
            }
        }
    }

    三、调用带有游标返回值的存储过程

      1.首先创建存储过程,这里需要使用包

        (1)声明包

    --声明包
    CREATE OR REPLACE
    PACKAGE MYPACKAGE AS
    
      type empcursor is REF CURSOR;
      PROCEDURE queryEmpList(pempno in NUMBER,empList out empcursor);
    
    END MYPACKAGE;

        (2)实现包体

    CREATE OR REPLACE
    PACKAGE BODY MYPACKAGE AS
    
      PROCEDURE queryEmpList(pempno in NUMBER,empList out empcursor) AS
      BEGIN
        open empList for select * from emp where pempno=empno;
      END queryEmpList;
    
    END MYPACKAGE;

        (3)PL/SQL匿名块测试

    --测试带有游标的out参数。
    set serveroutput on;
    declare
      pempno number;
      empList mypackage.empcursor;
      empRow emp%rowtype;
    begin 
      pempno:=7369;
      mypackage.queryemplist(pempno,empList);
      --open emplist;--注意一定不要再次open,因为游标只能打开一次,否则会报错。
        loop 
          fetch emplist into empRow;
          exit when emplist%notfound;
          dbms_output.put_line(empRow.ename||'的工资是:'||empRow.sal);
        end loop;
        null;
      close emplist;
    end;
    /

      2.调用存储过程

    package com.kdyzm.test;
    
    import java.sql.CallableStatement;
    import java.sql.Connection;
    import java.sql.ResultSet;
    
    import oracle.jdbc.OracleTypes;
    import oracle.jdbc.OracleCallableStatement;
    import com.kdyzm.dbutils.JDBCUtils;
    
    /*
     * 测试带有游标返回值的存储过程
     * @author kdyzm
     *
     */
    public class TestProcedureWithCursor {
        public static void main(String[] args) {
            Connection conn=null;
            CallableStatement cs=null;
            ResultSet rs=null;
            String sql="{call mypackage.queryemplist(?,?)}";
            try
            {
                conn=JDBCUtils.getConnection();
                cs=conn.prepareCall(sql);
                cs.setInt(1, 7521);
                cs.registerOutParameter(2, OracleTypes.CURSOR);
                cs.execute();
                OracleCallableStatement ocs=(OracleCallableStatement)cs;
                rs=ocs.getCursor(2);
                while(rs.next())
                {
                    System.out.print(rs.getInt("empno")+" ");
                    System.out.print(rs.getString("ename")+" ");
                    System.out.print(rs.getString("JOB")+" ");
                    System.out.print(rs.getInt("MGR")+" ");
                    System.out.print(rs.getDate("HIREDATE")+" ");
                    System.out.print(rs.getDouble("SAL")+" ");
                    System.out.print(rs.getInt("COMM")+" ");
                    System.out.print(rs.getInt("DEPTNO")+" ");
                    System.out.println();
                }
            }
            catch(Exception e)
            {
                e.printStackTrace();
            }
            finally{
                JDBCUtils.free(conn, cs, rs);
            }
        }
    }

      3.运行结果

      

  • 相关阅读:
    模拟出栈
    全排列 next_permutation 用法
    区间覆盖
    BFS GPLT L2-016 愿天下有情人都是失散多年的兄妹
    GPLT L2-014 列车调度
    图的联通分量个数统计(判断图是否联通)
    堆排序 GPLT L2-012 关于堆的判断
    牛客挑战赛 30 A 小G数数
    由树的中后序遍历求树的前层序遍历
    【HDOJ4699】Editor(对顶栈,模拟)
  • 原文地址:https://www.cnblogs.com/kuangdaoyizhimei/p/4754624.html
Copyright © 2011-2022 走看看