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
« 上一篇: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
« 上一篇: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