日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

Java中执行存储过程和函数(web基础学习笔记十四)

發布時間:2025/3/15 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java中执行存储过程和函数(web基础学习笔记十四) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、概述

如果想要執行存儲過程,我們應該使用 CallableStatement 接口。

CallableStatement 接口繼承自PreparedStatement 接口。所以CallableStatement 接口包含有Statement 接口和PreparedStatement 接口定義的全部方法,但是并不是所有的方法我們都要使用,主要使用的方法有這樣幾個:

CallableStatement 常用方法:

返回類型方法簽名說明
booleanexecute()

執行 SQL 語句,如果第一個結果是 ResultSet 對
象,則返回 true;如果第一個結果是更新計數或者沒
有結果,則返回 false

void

registerOutParameter(int parameterIndex,int sqlType)

按順序位置parameterIndex 將OUT 參數注冊為
JDBC 類型sqlType,sqlType 為Types 類中的常量

Type

getType(int?parameterIndex)

根據參數的序號獲取指定的 JDBC 參數的值。第一
個參數是 1,第二個參數是 2,依此類推

我們可以使用execute()方法來執行存儲過程。CallableStatement 為所有的數據庫提供了一種統一的標準形式調用存儲過程。所以,你將會看到我們使用execute()調用存儲過程的語法與在Oracle 中會所有不同。

為了獲得存儲過程或函數的返回值,我們需要使用 registerOutParameter()方法將返回的參數注冊為JDBC 的類型。 registerOutParameter()方法的第一個參數是參數的序號,第一個為1,第二個為2,以此類推。第二個參數需要一個int 值,用來標記JDBC 的類型,我們可以使用java.sql.Types 類中的常量來設置這個參數。比如VARCHAR、DOUBLE 等類型。如果類型不夠用,也可以從具體數據庫的驅動中尋找合適的類型常量。如果存儲過程或函數有返回值,這個方法是必須要調用的,否則無法得到返回值,甚至會發生異常。

CallableStatement 接口中定義了很多get 方法,用于獲取存儲過程返回的值,根據值的類型不同,你可以使用不同get 方法,比如getInt()、getString()、getDouble()等等。
我們看一下使用CallableStatement 接口執行存儲過程和函數的語法格式。

存儲過程:{call <procedure-name>[(<arg1>,<arg2>, ...)]}
函數:{?= call <procedure-name>[(<arg1>,<arg2>, ...)]}

如果要調用存儲過程,則使用第一種語法,就是開頭不帶問號的語法,call 后面是過程名,
如果沒有參數,可以省略小括號。

如果要調用函數,則使用第二種語法,開頭帶有一個問號加等號,實際上這個問號就是一個占位符,這個問號總是調用函數的第一個占位符。其它部分與過程的語法相同

二、CallableStatement 執行存儲過程

2.1、建立基類

package com.pb.emp.dao;import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException;import com.pb.emp.untily.ConfigManager;public class BaseDao {protected Connection conn;protected PreparedStatement ps;protected ResultSet rs;//建立連接public boolean getConnection(){String driver=ConfigManager.getInstance().getString("jdbc.driver_class");String url=ConfigManager.getInstance().getString("jdbc.connection.url");String username=ConfigManager.getInstance().getString("jdbc.connection.username");String password=ConfigManager.getInstance().getString("jdbc.connection.password");try {Class.forName(driver);conn=DriverManager.getConnection(url,username, password);} catch (ClassNotFoundException e) {// TODO Auto-generated catch block e.printStackTrace();return false;} catch (SQLException e) {// TODO Auto-generated catch block e.printStackTrace();return false;}return true;}//增加,修改,刪除public int executeUpdate(String sql, Object[] params){getConnection();int updateRow=0;try {ps=conn.prepareStatement(sql);//填充占位符for(int i=0;i<params.length;i++){ps.setObject(i+1, params[i]);}updateRow = ps.executeUpdate();} catch (SQLException e) {// TODO Auto-generated catch block e.printStackTrace();}return updateRow;}////查詢public ResultSet executeSQL(String sql, Object[] params){getConnection();try {ps=conn.prepareStatement(sql);//填充占位符for(int i=0;i<params.length;i++){ps.setObject(i+1, params[i]);}rs = ps.executeQuery();} catch (SQLException e) {// TODO Auto-generated catch block e.printStackTrace();}return rs;}// 關閉資源public boolean closeResource() {if(rs!=null){try {rs.close();} catch (SQLException e) {// TODO Auto-generated catch block e.printStackTrace();return false;}}if(ps!=null){try {ps.close();} catch (SQLException e) {// TODO Auto-generated catch block e.printStackTrace();return false;}}if(conn!=null){try {conn.close();} catch (SQLException e) {// TODO Auto-generated catch block e.printStackTrace();return false;}}return true;} }

2.2、執行不帶參但是有返回值的存儲過程

新建類來繼承上面的類也可以繼承,下面建立存儲過程

--查詢emp表記錄數 CREATE OR REPLACE PROCEDURE getEmpCount(v_count OUT NUMBER) AS BEGINSELECT COUNT(*) INTO v_count FROM emp; END;

調用

//執行不帶參但是有返回值的存儲過程獲取emp表總記錄數public int getTotalCountProc(){//定義一個變量來接收結果int totalCount=0;//聲明CallableStatement對象CallableStatement proc=null;String sql="{call getEmpCount(?)}";try {//建立連接 getConnection();//CallableStatement對象proc=conn.prepareCall(sql);//將數據庫對象數據類型注冊為java中的類型proc.registerOutParameter(1, Types.INTEGER);//執行 proc.execute();//接收返回值totalCount=proc.getInt(1);} catch (SQLException e) {// TODO Auto-generated catch block e.printStackTrace();}return totalCount;}

2.3、執行帶參帶返回值的存儲過程

--根據部門編號和姓名查詢人數 CREATE OR REPLACE PROCEDURE getEmpCount(v_deptno NUMBER, v_ename VARCHAR2,v_count OUT NUMBER) AS BEGIN SELECT COUNT(*) INTO v_count FROM emp WHERE ename LIKE '%'||v_ename||'%' AND deptno=v_deptno; END; //執行帶參帶返回值的存儲過程public int getTotalCountProc1(int deptno,String ename){//定義一個變量來接收結果int totalCount=0;//聲明CallableStatement對象CallableStatement proc=null;String sql="{call getEmpCount(?,?,?)}";//建立連接 getConnection();//CallableStatement對象try {proc=conn.prepareCall(sql);//設置占位符//Object [] params={deptno,ename};//只設置輸入參數即可proc.setInt(1, deptno);proc.setString(2, ename);//proc.setInt(3, totalCount);將數據庫對象數據類型注冊為java中的類型,將輸出參數轉換proc.registerOutParameter(3, Types.INTEGER);//執行 proc.execute();//獲取結果totalCount=proc.getInt(3);} catch (SQLException e) {// TODO Auto-generated catch block e.printStackTrace();}finally{this.closeResource();if(proc!=null){try {proc.close();} catch (SQLException e) {// TODO Auto-generated catch block e.printStackTrace();}}}return totalCount;}

2.3、執行返回值為游標的存儲過程

--查詢員工所有信息 CREATE OR REPLACE PROCEDURE emp_cur(emp_cur OUT SYS_REFCURSOR) AS BEGINOPEN emp_cur FOR SELECT * FROM emp; END; //執行返回值為游標的存儲過程 游標名emp_curpublic List<Emp> getempProc1(){List<Emp> emplist=new ArrayList<Emp>();String sql="{call emp_cur(?) }";//聲明CallableStatement對象CallableStatement proc=null;//建立連接getConnection();try {//執行proc=conn.prepareCall(sql);//注冊類型為數據庫游標類型proc.registerOutParameter(1, oracle.jdbc.OracleTypes.CURSOR);//接收結果集proc.execute();//獲取結果第一個對象rs=(ResultSet) proc.getObject(1);while(rs.next()){int empno=rs.getInt("empno"); String ename=rs.getString("ename"); String job=rs.getString("job"); int mgr=rs.getInt("mgr"); Date hiredate=rs.getDate("hiredate"); double sal=rs.getDouble("sal"); double comm=rs.getDouble("comm"); int deptno=rs.getInt("deptno");//聲明Emp對象Emp emp=new Emp();//將得到的值添加到對象中emp.setEmpno(empno);emp.setEname(ename);emp.setJob(job);emp.setMgr(mgr);emp.setHiredate(hiredate);emp.setSal(sal);emp.setComm(comm);emp.setDeptno(deptno);//將對象添加到集合emplist.add(emp);}} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}finally{this.closeResource();if(proc!=null){try {proc.close();} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}return emplist;}

以上看出,需要將輸出的參數,和結果注冊,輸入的參數不要注冊,

但輸入參數需要設置占位符

三、執行函數

3.1 、函數功能為根據雇員id 返回姓名

CREATE OR REPLACE FUNCTION getename(v_empno NUMBER) RETURN VARCHAR2 AS v_ename VARCHAR2(20);BEGINSELECT ename INTO v_ename FROM emp WHERE empno=v_empno;RETURN v_ename; END; public void getenamefun(int empno){//sqlString ename="";String sql="{?=call getename(?)}";CallableStatement fun=null;getConnection();try {fun=conn.prepareCall(sql);fun.setInt(2, empno);fun.registerOutParameter(1, Types.VARCHAR);fun.execute();ename=fun.getString(1);System.out.println(ename);} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}}

其它的方法與過程一樣,只是多了個返回值類型

?

轉載于:https://www.cnblogs.com/liunanjava/p/4261242.html

總結

以上是生活随笔為你收集整理的Java中执行存储过程和函数(web基础学习笔记十四)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。