Java 調用存儲過程 返回結果集

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(); //關閉鏈接
    }
}
相關文章
相關標籤/搜索