JDBC调用存储过程和函数

JDBC调用存储过程和函数

在数据库中我们可以写一些存储过程和函数,来封装一些常用的SQL语句,存储过程和函数目的是为了可重复地执行操作数据库的sql语句的集合

返回值上:

  • 存储过程的返回值,可以有多个值
  • 函数的返回值,只有一个值

函数是可以嵌入在SQL中使用的,可以在SELECT等SQL语句中调用,而存储过程则不行。我们可以在数据库中创建一些常用的存储过程和函数,这样我们在数据访问层直接调用即可。这里记录一下使用JDBC调用存储过程和函数的方法

调用没有返回值的存储过程

首先我们在数据库中创建一个没有返回值的存储过程:

create or replace procedure proc_Ins_Dept(vid in varchar2 ,vname  in varchar2,vloc in varchar2) is
begin insert into Dept values(vid,vname,vloc);
end proc_Ins_Dept;

我是在Oracle中创建的,其他的数据库大同小异

在Dao中调用:

复制代码

// 无返回值的存储过程
    public void proc1() {
        try {

            Connection conn = super.getConn();    //调用了BaseDao创建连接

            CallableStatement cs = conn.prepareCall("{call proc_Ins_Dept(?,?,?)}");  //调用格式 {call 存储过程名(参数)}
            cs.setObject(1, 76);
            cs.setObject(2, "技术部");
            cs.setObject(3, "zhengzhou");
            cs.execute();            //执行
            cs.close();
            conn.close();

        } catch (Exception ex) {
            ex.printStackTrace();
        }

    }

复制代码

调用有返回值的存储过程

创建有返回值的存储过程:

复制代码

create or replace procedure pro_Ins_Dept (vid in varchar2,vname in varchar2,vloc in varchar2,vresult out varchar2) is 
begin insert into Dept values(vid,vname,vloc);
  vresult:='success';
Exception
  when others then
   vresult:='fail';
end pro_Ins_Dept;

复制代码

输入值使用in,返回值使用out表示

在Dao中调用:

复制代码

// 带返回值的存储过程
    public void proc2() {
        try {
            Connection conn = super.getConn();
            CallableStatement cs = conn.prepareCall("{call proc_Ins_Dept2(?,?,?,?)}");
            cs.setObject(1, 76);
            cs.setObject(2, "市场部");
            cs.setObject(3, "luoyang");
            cs.registerOutParameter(4, java.sql.Types.VARCHAR);           //注册返回类型(sql类型)
            cs.execute();

            Object objRtn = cs.getObject(4);      //得到返回值

            System.out.println(objRtn);

            cs.close();
            conn.close();

        } catch (Exception ex) {
            ex.printStackTrace();
        }

    }

复制代码

唯一不同的是我们需要给返回值注册类型,可以在java.sql.Types类中找到对应的Sql类型,Oracle中的varchar2对应的也是varchar。最后使用CallableStatement的get方法得到返回结果

调用自定义函数

SQL语句:

create or replace function fun_avg_dept(vdeptno in number)
    return number is 
       r number;
begin select avg(sal) into r from emp where deptno=vdeptno;
       return(r);
end fun_avg_dept;

Dao中调用:

复制代码

    // 带返回值的自定义函数
    public void fun1() {
        try {
            Connection conn = super.getConn();
                           
            //函数可以嵌入到Sql中
            String sql = "select fun_avg_dept(?) from dual";

            //调用方式还是和使用ps调用普通SQL一样
            PreparedStatement ps = conn.prepareStatement(sql);

            ps.setObject(1, 10);

            ResultSet rs = ps.executeQuery();

            if (rs.next()) {
                System.out.println(rs.getObject(1));
            }

            rs.close();
            ps.close();
            conn.close();

        } catch (Exception ex) {
            ex.printStackTrace();
        }

    }

复制代码

标签: JavaEE笔记

https://www.cnblogs.com/lz2017/p/7500411.html

随笔- 51  文章- 1  评论- 0 

如何使用 JDBC 调用存储在数据库中的函数或存储过程

JDBC调用存储过程
步骤:
1 通过Connection对象的prepareCall()方法创建一个CallableStatement对象的实例。在使用Connection对象的prepareCall()方法时,需要传入一个String类型的字符串,该字符串用于指明如何调用存储过程
{?= call <procedure-name>[(<arg1>,<arg2>, ...)]}
{call <procedure-name>[(<arg1>,<arg2>, ...)]}

2 通过CallableStatement对象的registerOutParameter()方法注册OUT参数
3 通过CallableStatement对象的setXxx()方法设定IN或IN OUT参数
若想将参数默认值设为Null,可以使用setNull()方法
4 通过CallableStatement对象的execute()方法执行存储过程
5 如果所调用的是带返回参数的存储过程,还需要通过CallableStatement对象的getXxx()方法获取其返回值
注:通过数据字典查看存储过程或函数的定义

select text from user_source where lower(name)='add_fun';
调用函数:

package com.atguigu.jdbc;

import static org.junit.Assert.*;

import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Types;

import javax.sql.DataSource;

import org.junit.Test;

import com.mchange.v2.c3p0.ComboPooledDataSource;

public class JDBCTest {

/**
* 如何使用 JDBC 调用存储在数据库中的函数或存储过程
*/
@Test
public void testCallableStatment() {

Connection connection = null;
CallableStatement callableStatement = null;

try {
connection = JDBCTools.getConnection();

// 1. 通过 Connection 对象的 prepareCall()
// 方法创建一个 CallableStatement 对象的实例.
// 在使用 Connection 对象的 preparedCall() 方法时,
// 需要传入一个 String 类型的字符串, 该字符串用于指明如何调用存储过程.
String sql = "{?= call sum_salary(?, ?)}";
callableStatement = connection.prepareCall(sql);

// 2. 通过 CallableStatement 对象的 
//reisterOutParameter() 方法注册 OUT 参数.
callableStatement.registerOutParameter(1, Types.NUMERIC);
callableStatement.registerOutParameter(3, Types.NUMERIC);

// 3. 通过 CallableStatement 对象的 setXxx() 方法设定 IN 或 IN OUT 参数. 若想将参数默认值设为
// null, 可以使用 setNull() 方法.
callableStatement.setInt(2, 80);

// 4. 通过 CallableStatement 对象的 execute() 方法执行存储过程
callableStatement.execute();

// 5. 如果所调用的是带返回参数的存储过程, 
//还需要通过 CallableStatement 对象的 getXxx() 方法获取其返回值.
double sumSalary = callableStatement.getDouble(1);
long empCount = callableStatement.getLong(3);

System.out.println(sumSalary);
System.out.println(empCount);

} catch (Exception e) {
e.printStackTrace();
} finally {
JDBCTools.releaseDB(null, callableStatement, connection);
}


}

@Test
public void testC3P0() throws SQLException {
DataSource dataSource = new ComboPooledDataSource("c3p0");

System.out.println(dataSource.getConnection());
}

}

标签: JDBC

好文要顶 关注我 收藏该文  

苍狼哂啡
关注 - 3
粉丝 - 1

+加关注

« 上一篇:c3p0数据库连接池使用--创建JDBCTools 公共类
» 下一篇:如何使用JDBC调用存储在数据库中的函数或存储过程 */

https://www.cnblogs.com/xiaona19841010/p/5223779.html

JDBC学习笔记(10)——调用函数&存储过程

如何使用JDBC调用存储在数据库中的函数或存储过程:

* 1.通过COnnection对象的prepareCall()方法创建一个CallableStatement
*    对象的实例,在使用Connection对象的prepareCall() 方法时,需要传入一个String类型的字符串,
*    该字符串用于指明如何调用存储过程

* 2.通过CallableStatement对象的registerOutParameter() 方法注册Out参数

* 3.通过CallableStatement对象的setXxx()方法设定IN或In out
*    参数,若想将参数设为null,可以使用setNUll()

* 4.通过CallableStatement对象的execute()方法执行存储过程

* 5.如果所调用的是带返回参数的存储过程没还需要通过CallableStatement对象的getXxx()函数进行获取

具体的代码实现:

复制代码

 1     @Test
 2     public void testCallableStatement() {
 3         Connection connection = null;
 4         /**
 5          * 调用存储函数 1.{?= call <procedure-name>[(<arg1>,<arg2>, ...)]} 
 6          * 调用存储过程 2.{call <procedure-name>[(<arg1>,<arg2>, ...)]}
 7          */
 8         // 调用存储函数和调用存储过程,一个sql语句的区别
 9         String sql = "{?= call <procedure-name>[(<arg1>,<arg2>, ...)]}";
10         CallableStatement callableStatement = null;
11         try {
12 
13             connection = JDBCTools.getConnection();
14             /*
15              * 1.通过COnnection对象的prepareCall()方法创建一个CallableStatement
16              * 对象的实例,在使用Connection对象的prepareCall() 方法时,需要传入一个String类型的字符串,
17              * 该字符串用于指明如何调用存储过程
18              */
19             callableStatement = connection.prepareCall(sql);
20 
21             /*
22              * 2.通过CallableStatement对象的registerOutParameter() 方法注册Out参数
23              */
24             callableStatement.registerOutParameter(1, Types.NUMERIC);
25             callableStatement.registerOutParameter(3, Types.NUMERIC);
26 
27             /*
28              * 3.通过CallableStatement对象的setXxx()方法设定IN或In out
29              * 参数,若想将参数设为null,可以使用setNUll()
30              */
31             callableStatement.setInt(2, 80);
32 
33             /* 4.通过CallableStatement对象的execute()方法执行存储过程 */
34             callableStatement.execute();
35 
36             /*
37              * 5.如果所调用的是带返回参数的存储过程没还需要通过CallableStatement对象的getXxx()
38              */
39             double sumSalary = callableStatement.getDouble(1);
40             long empCount = callableStatement.getLong(3);
41         } catch (Exception e) {
42             e.printStackTrace();
43         } finally {
44             JDBCTools.release(null, callableStatement, connection);
45         }
46     }

复制代码

调用函数和存储过程的sql语句的区别:

* 调用存储函数 1.{?= call <procedure-name>[(<arg1>,<arg2>, ...)]} 
* 调用存储过程 2.{call <procedure-name>[(<arg1>,<arg2>, ...)]}

这个知识点暂时没用到,先做下笔记,待以后用到以后再深入研究,JDBC的学习暂时告一段落,开启新的学习征程!


个人感悟:把简单的事情做到极致,打扎实的基础,写优秀的代码

本文为博主原创文章,转载请注明出处:http://www.cnblogs.com/ysw-go/
1、本博客的原创原创文章,都是本人平时学习所做的笔记,如有错误,欢迎指正。
2、如有侵犯您的知识产权和版权问题,请通知本人,本人会即时做出处理文章。
3、本博客的目的是知识交流所用,转载自其它博客或网站,作为自己的参考资料的,感谢这些文章的原创人员

分类: JDBC

好文要顶 关注我 收藏该文  

菜鸟奋斗史
关注 - 23
粉丝 - 131

+加关注

« 上一篇:JDBC学习笔记(9)——DBUtils的使用
» 下一篇:HTML+CSS+JS学习总结

https://www.cnblogs.com/ysw-go/p/5480675.html

java实现存储过程并同时得到out与return的值

置顶 2017年07月09日 15:12:40 风雪夜归人提示已存在 阅读数:637 标签: java存储过程数据库

@Test
public final void test() {
SessionFactory sf = baseDao4.getSessionFactory();//任意穿件一个session
Session session = sf.openSession();
try{
       //session.beginTransaction(); //如果有spring来管理事务,记得注销这句
        session.doWork(
        new Work() {
@Override
public void execute(Connection connection) throws SQLException {
CallableStatement cs = connection.prepareCall("{?=CALL GSP_GR_DISTRIBUTOR(?,?,?,?,?,?)}"); //第一个?是return的值  //最后一个是out的值. jdbc下标从1开始.hibernate是从0开始.坑爹了.
cs.registerOutParameter(1,java.sql.Types.INTEGER);
                   cs.setInt(2, 999999);
                   cs.setInt(3, 1);    
                   cs.setInt(4, 1);    
                   cs.setInt(5, 1);    
                   cs.setInt(6, 1);  
                   cs.registerOutParameter(7,java.sql.Types.NVARCHAR);
                   cs.execute();
                   int a = cs.getInt(1);
                   System.out.println(a);
                   String result = cs.getString(7);
        System.out.println(result);
/*
* 可用
Statement s = connection.createStatement();
String sql = "select * from RechargeRecord";
    ResultSet rs = s.executeQuery(sql);
    
    while(rs.next()){
    System.out.println(rs.getInt(1));
    }*/
}

        );
     //    session.getTransaction().commit();
       
   }catch(Exception e){
      e.printStackTrace();
   }
   finally{
      session.close();  //如果用spring管理,也需要这就关闭连接.
   }

}

https://blog.csdn.net/qq_38024577/article/details/74887053


 

狐小仙

JDBC操作存储过程、存储函数、out参数使用游标

JDBC工具类

复制代码

public class JDBCUtils {
    private static String driver = "oracle.jdbc.OracleDriver";
    private static String url = "jdbc:oracle:thin:@192.168.79.128:1521/orcl";
    private static String user = "scott";
    private static String password = "tiger";
    
    
    static{
        //注册驱动
        //DriverManager.registerDriver(driver)
        try {
            Class.forName(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; ///-----> 原因:Java GC: Java的GC不受代码的控制
            }
        }
        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;
            }
        }
    }
}

复制代码

存储过程

复制代码

--存储过程
create or replace procedure queryEmpInformation(eno in number,
                                                pename out varchar2,
                                                psal out number,
                                                pjob out varchar2)
is
begin
  select ename,sal,job into pename,psal,pjob from emp where empno = eno;
end queryEmpInformation;

复制代码

java代码

复制代码

@Test
    public void testProcedure(){
        //jdbc调用存储过程sql语句:
        //{call <procedure-name>[(<arg1>,<arg2>, ...)]}
        String sql = "{call queryEmpInformation(?,?,?,?)}";
        
        Connection conn = null;
        CallableStatement call = null;
        
        try{
            conn = JDBCUtils.getConnection();
            call = conn.prepareCall(sql);
            
            //输入参数赋值
            call.setInt(1, 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+"\t"+sal+"\t"+job);
        }catch (Exception e){
            e.printStackTrace();
        }finally{
            JDBCUtils.release(conn, call, null);
        }
    }

复制代码

存储函数

复制代码

--存储函数
create or replace function queryEmpIncome(eno in number)
return number
is
psal emp.sal%type;
pcomm emp.comm%type;
begin
  select sal,comm into psal,pcomm from emp where empno = eno;
  return psal*12+nvl(pcomm,0);
end queryEmpIncome;

复制代码

java代码

复制代码

@Test
    public void testFuntion(){
        //jdbc调用存储函数sql语句:
        //{?= call <procedure-name>[(<arg1>,<arg2>, ...)]}
        String sql = "{? = call queryEmpIncome(?)}";
        
        Connection conn = null;
        CallableStatement call = null;
        
        try{
            conn = JDBCUtils.getConnection();
            call = conn.prepareCall(sql);
            
            //注册输出参数
            call.registerOutParameter(1, OracleTypes.NUMBER);
            //输入参数
            call.setInt(2, 7839);
            
            //执行
            call.execute();
            
            //取出返回值
            double income = call.getDouble(1);
            System.out.println("年薪:"+income);
        }catch (Exception e){
            e.printStackTrace();
        }finally{
            JDBCUtils.release(conn, call, null);
        }
    }

复制代码

out参数游标

复制代码

--创建包头
create or replace package mypackage 
is
--定义一个cursor类型变量
type empcursor is ref cursor;
procedure queryEmpList(dno in number,empList out empcursor);
end mypackage;


--创建包体
create or replace package body mypackage is
  procedure queryEmpList(dno in number,empList out empcursor)
    as
    begin
      open empList for select * from emp where deptno = dno;
      end;
end mypackage;

复制代码

java代码

复制代码

@Test
    public void testCursor(){
        String sql = "call mypackage.queryEmpList(?,?)";
        
        Connection conn = null;
        CallableStatement call = null;
        ResultSet rs = null;
        
        try{
            conn = JDBCUtils.getConnection();
            call = conn.prepareCall(sql);
            
            call.setInt(1, 20);
            call.registerOutParameter(2, OracleTypes.CURSOR);
            
            call.execute();
            
            rs = ((OracleCallableStatement)call).getCursor(2);
            while(rs.next()){
                String name = rs.getString("ename");
                double sal = rs.getDouble("sal");
                System.out.println(name+"\t"+sal);
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally{
            JDBCUtils.release(conn, call, null);
        }
    }

复制代码

分类: Java

好文要顶 关注我 收藏该文  

狐小仙
关注 - 0
粉丝 - 0

+加关注

0

0

« 上一篇:存储过程函数
» 下一篇:触发器

posted on 2018-08-01 17:22 狐小仙 阅读(184) 评论(0) 编辑 收藏

https://www.cnblogs.com/zsh-wj/p/9402486.html

猜你喜欢

转载自blog.csdn.net/xuheng8600/article/details/85250614