1 createorreplaceprocedure proc3(stid in student.stuid%type, stname out student.sname%type, stphone out student.phonenumber%type, stuadd out student.saddress%type) 2 as countnumber number; 3 begin 4 selectcount(*) into countnumber from student where stuid=stid; 5 if countnumber=1then 6 select phonenumber into stphone from student where stuid=stid; 7 select saddress into stuadd from student where stuid=stid; 8 select sname into stname from student where stuid=stid; 9 else 10 dbms_output.put_line('返回值過多'); 11 endif; 12 end;
調用存儲過程時,要用CallabelStatement的prepareCall 方法。結構:{call 存儲過程名(?,?,...)}java
在設置參數的時候,輸入參數用set,輸出參數要registerOutParameter。取出輸出參數的值能夠直接用CallabelStatement的get方法sql
import java.sql.CallableStatement; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Types; public class Dao { String driver="oracle.jdbc.driver.OracleDriver"; String url="jdbc:oracle:thin:@127.0.0.1:1521:orcl"; Connection conn=null; CallableStatement cs=null;//PreparedStatement,Statement ResultSet rs; public void getConn(){ try { Class.forName(driver); conn = DriverManager.getConnection(url, "scott", "tiger"); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } } public void callProc(){ try { cs = conn.prepareCall("{call proc3(?,?,?,?)}"); cs.setInt(1, 1); cs.registerOutParameter(2, Types.VARCHAR); cs.registerOutParameter(3, Types.VARCHAR); cs.registerOutParameter(4, Types.VARCHAR); cs.execute(); String name = cs.getString(2); String phone = cs.getString(3); String address = cs.getString(4); System.out.println("Name:"+name+"\t Phone:"+phone+"\t Address:"+address); } catch (SQLException e) { e.printStackTrace(); }finally{ try { if (cs!=null) cs.close(); if(conn!=null) conn.close(); } catch (SQLException e) { e.printStackTrace(); } } } public static void main(String[] args) { Dao dao = new Dao(); dao.getConn(); dao.callProc(); } }
以上方法只支持返回個別數據的,不能像SQL返回結果集類型那樣。其實,Oracle並不能直接用存儲過程來返回結果集,須要借用包才能實現。看代碼:oracle
1 CREATEORREPLACE PACKAGE mypack IS 2 TYPE mycursor IS REF CURSOR; 3 PROCEDURE myproc(outcursor IN OUT mycursor); 4 END mypack;
這裏建了一個包,其中有兩個元素:mycursor遊標和myproc存儲過程。執行該語句以後要再定義這個包中的內容,代碼以下:app
1 CREATEORREPLACE PACKAGE BODY mypack IS 2 PROCEDURE myproc( 3 outcursor IN OUT mycursor 4 ) 5 IS 6 BEGIN 7 OPEN outcursor FOR 8 SELECT*FROM Student WHERE ROWNUM<10; 9 RETURN; 10 END myproc; 11 END;
這裏詳細定義了mycursor和myproc的body。注意:CREATE PACKAGE和CREATE PACKAGE BODY不能一塊兒執行,必須前後執行,不然會報錯(用goto;鏈接是能夠的)。OKay,包和存儲過程定義好了,該寫Java代碼了:ui
import java.sql.CallableStatement; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Types; import oracle.jdbc.OracleTypes; publicclass Dao { String driver="oracle.jdbc.driver.OracleDriver"; String url="jdbc:oracle:thin:@127.0.0.1:1521:orcl"; Connection conn=null; CallableStatement cs=null;//PreparedStatement,Statement ResultSet rs; publicvoid getConn(){ try { Class.forName(driver); conn = DriverManager.getConnection(url, "scott", "tiger"); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } } publicvoid callProc(){ try { cs = conn.prepareCall("{call proc3(?,?,?,?)}"); cs.setInt(1, 1); cs.registerOutParameter(2, Types.VARCHAR); cs.registerOutParameter(3, Types.VARCHAR); cs.registerOutParameter(4, Types.VARCHAR); cs.execute(); String name = cs.getString(2); String phone = cs.getString(3); String address = cs.getString(4); System.out.println("Name:"+name+"\t Phone:"+phone+"\t Address:"+address); } catch (SQLException e) { e.printStackTrace(); } } publicvoid callProcForResult(){ try { cs = conn.prepareCall("{call mypack.myproc(?)}"); cs.registerOutParameter(1, OracleTypes.CURSOR); cs.execute(); ResultSet rs = (ResultSet)cs.getObject(1); while(rs!=null&& rs.next()){ System.out.println(new StringBuilder("ID:").append(rs.getInt(1)).append("\t Name:").append(rs.getString(2)) .append("\t Phone:").append(rs.getString(6)).append("\t Address:").append(rs.getString(7)).toString()); } } catch (SQLException e) { e.printStackTrace(); } } publicvoid closeConn(){ try { if (cs!=null) cs.close(); if(conn!=null) conn.close(); } catch (SQLException e) { e.printStackTrace(); } } publicstaticvoid main(String[] args) { Dao dao =new Dao(); dao.getConn(); //獲得鏈接 dao.callProc(); //調用返回單屬性的存儲過程 dao.callProcForResult(); //調用返回結果集的存儲過程 dao.closeConn(); //關閉鏈接 } }