1. 程式人生 > >JDBC呼叫儲存過程和函式

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