疑問:怎樣判斷存儲過程執行以後返回值是否爲空。java
1、鏈接oracle數據庫sql
1.須要的jar包:在安裝的oracle中就有,因此不須要到官網下載,個人oracle11g下:D:\app\kdyzm\product\11.2.0\dbhome_1\jdbc\lib,文件夾中有若干.jar文件,選擇ojdbc6.jar便可。數據庫
2.鏈接oracleoracle
驅動位置:oracle.jdbc.OracleDriverapp
url寫法:jdbc:oracle:thin:@localhost:1521:orcl函數
3.JDBCUtilsoop
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); } }
2、調用存儲過程fetch
1.使用CallableStatement標準接口。url
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); } } }
3、調用存儲函數
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); } } }
3、調用帶有遊標返回值的存儲過程
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.運行結果