statement、prepareStatement、callableStatement的使用

CallableStatement 對象爲所有的DBMS 提供了一種以標準形式調用已儲存過程的方法。已儲 存過程儲存在數據庫中。對已儲存過程的調用是 CallableStatement對象所含的內容。這種調用是 用一種換碼語法來寫的,有兩種形式:一種形式帶結果參,另一種形式不帶結果參數。結果參數是 一種輸出 (OUT) 參數,是已儲存過程的返回值。兩種形式都可帶有數量可變的輸入(IN 參數)、 輸出(OUT 參數)或輸入和輸出(INOUT 參數)的參數。問號將用作參數的佔位符。

1.帶?參數的使用prepareStatement。這也是使用最多的。

public void addCategory(Category category) {  
        String sql = "insert into category values(seque_cid.nextval,?,?)";  
        PreparedStatement pstmt = null;  
        try {  
            pstmt = conn.prepareStatement(sql);  
            pstmt.setString(1, category.getCname());  
            pstmt.setString(2, category.getCdesc());  
            pstmt.executeUpdate();  
        } catch (SQLException e) {  
            e.printStackTrace();  
        }finally{  
            //關閉  
                if(pstmt!=null){  
                    try {  
                        pstmt.close();  
                    } catch (SQLException e) {  
                        e.printStackTrace();  
                    }  
                }  
                if(conn!=null){  
                    try {  
                        conn.close();  
                    } catch (SQLException e) {  
                        e.printStackTrace();  
                    }  
                }  
        }  
          
    } 



public void addCategory(Category category) {
		String sql = "insert into category values(seque_cid.nextval,?,?)";
		PreparedStatement pstmt = null;
		try {
			pstmt = conn.prepareStatement(sql);
			pstmt.setString(1, category.getCname());
			pstmt.setString(2, category.getCdesc());
			pstmt.executeUpdate();
		} catch (SQLException e) {
			e.printStackTrace();
		}finally{
			//關閉
				if(pstmt!=null){
					try {
						pstmt.close();
					} catch (SQLException e) {
						e.printStackTrace();
					}
				}
				if(conn!=null){
					try {
						conn.close();
					} catch (SQLException e) {
						e.printStackTrace();
					}
				}
		}
		
	}

 2.不帶參數,例如查所用,不需要到任何參數。使用statement。

public List<Category> getAllCategorys() {  
    List<Category>list = new ArrayList<Category>();  
    String sql = "select * from category ";  
    Category c = null;  
    Statement stmt = null;  
    ResultSet rs = null;  
    try {  
        stmt = conn.createStatement();  
        rs = stmt.executeQuery(sql);  
        while(rs.next()){  
            c = new Category();  
            c.setCid(rs.getInt(1));  
            c.setCname(rs.getString(2));  
            c.setCdesc(rs.getString(3));  
            list.add(c);  
        }  
    } catch (SQLException e) {  
        e.printStackTrace();  
    }finally{  
        //關閉  
        if(rs!=null){  
            try {  
                rs.close();  
            } catch (SQLException e) {  
                  
                e.printStackTrace();  
            }  
        }  
        if(stmt!=null){  
            try {  
                stmt.close();  
            } catch (SQLException e) {  
                e.printStackTrace();  
            }  
        }  
        if(conn!=null){  
            try {  
                conn.close();  
            } catch (SQLException e) {  
                e.printStackTrace();  
            }  
        }  
    }  
    return list;  
}  

 3.調用存儲過程的CallableStatement。

 

特別注意,存儲過程的輸出參數需要先進行註冊

public void callProcedure() {  
        String sql = "{call proce_bigger(?,?,?,?)}";  
        CallableStatement cstmt = null;  
        try {  
            cstmt = conn.prepareCall(sql);  
            cstmt.setInt(1, 10);  
            cstmt.setInt(2, 13);  
            cstmt.registerOutParameter(3, Types.INTEGER);  
            cstmt.registerOutParameter(4, Types.INTEGER);  
            cstmt.setInt(4, 6);  
            cstmt.executeUpdate();  
            System.out.println(cstmt.getInt(3));  
            System.out.println(cstmt.getInt(4));  
        } catch (Exception e) {  
            e.printStackTrace();  
        }finally{  
            //關閉  
            if(cstmt!=null){  
                try {  
                    cstmt.close();  
                } catch (SQLException e) {  
                    e.printStackTrace();  
                }  
            }  
            if(conn!=null){  
                try {  
                    conn.close();  
                } catch (SQLException e) {  
                    e.printStackTrace();  
                }  
            }  
        }  
          
    } 
1  使用不帶參數的存儲過程  

public static void executeStoredProcedure(Connection con) {  
        try {  
            CallableStatementcstmt = con  
                    .prepareCall("{calldbo.GetContactFormalNames}");  
            ResultSetrs = cstmt.executeQuery();  
            while (rs.next()) {  
                System.out.println(rs.getString("FormalName"));  
            }  
        } catch (Exception e) {  
            e.printStackTrace();  
        } finally {  
            rs.close();  
            cstmt.close();  
        }  
    }  

2 使用帶有輸入參數的存儲過程 

 

public static void executeStoredProcedure(Connection con) {  
        try {  
            CallableStatementcstmt = con  
                    .prepareCall("{call dbo.uspGetEmployeeManagers(?)}");  
            cstmt.setInt(1, 50);  
            ResultSetrs = cstmt.executeQuery();  
            while (rs.next()) {  
                System.out.println("EMPLOYEE:");  
                System.out.println(rs.getString("LastName") + ", "  
                        + rs.getString("FirstName"));  
                System.out.println("MANAGER:");  
                System.out.println(rs.getString("ManagerLastName") + ", "  
                        + rs.getString("ManagerFirstName"));  
                System.out.println();  
            }  
        }  
  
        catch (Exception e) {  
            e.printStackTrace();  
        } finally {  
            rs.close();  
            cstmt.close();  
        }  
    }  

3 使用帶有輸出參數的存儲過程 

 public static void executeStoredProcedure(Connection con) {  

        try {  
            CallableStatementcstmt = con  
                    .prepareCall("{call dbo.GetImmediateManager(?, ?)}");  
            cstmt.setInt(1, 5);  
            cstmt.registerOutParameter(2, java.sql.Types.INTEGER);  
            cstmt.execute();  
            System.out.println("MANAGER ID: " + cstmt.getInt(2));  
        } catch (Exception e) {  
            e.printStackTrace();  
        }  
    }  

4 使用帶有返回狀態的存儲過程(目前測試狀態返回只能是int類型) 

作爲示例,在 SQL Server 2005 AdventureWorks 示例數據庫中創建以下存儲過程: 

 CREATE PROCEDURE CheckContactCity @cityNameCHAR(50)ASBEGIN IF ((SELECT COUNT(*) FROM Person.Address WHERE City = @cityName) > 1) RETURN 1ELSE RETURN 0END   

public static void executeStoredProcedure(Connection con) {  
        try {  
            CallableStatementcstmt = con  
                    .prepareCall("{? = call dbo.CheckContactCity(?)}");  
            cstmt.registerOutParameter(1, java.sql.Types.INTEGER);  
            cstmt.setString(2, "Atlanta");  
            cstmt.execute();  
            System.out.println("RETURN STATUS: " + cstmt.getInt(1));  
        }  
          
        catch (Exception e) {  
            e.printStackTrace();  
        }finally{  
            cstmt.close();   
        }  
    }  

 

注:在sql中執行該存儲過程的方法: declare @c int 

exec @c=CheckContactCity 'Atlanta' print @c 

5 使用帶有更新記數的存儲過程 

作爲示例,在 SQL Server 2005 AdventureWorks 示例數據庫中創建以下表和存儲過程: 

 CREATE TABLE TestTable (Col1 int IDENTITY, Col2 varchar(50), Col3 int);    

CREATE PROCEDURE UpdateTestTable   
      @Col2 varchar(50),       @Col3 int AS BEGIN   
      UPDATE TestTable   
      SET Col2 = @Col2, Col3 = @Col3 END;   
public static void executeUpdateStoredProcedure(Connection con) {
		try {
			CallableStatementcstmt = con
					.prepareCall("{call dbo.UpdateTestTable(?, ?)}");
			cstmt.setString(1, "A");
			cstmt.setInt(2, 100);
			cstmt.execute();
			int count = cstmt.getUpdateCount();
			System.out.println("ROWS AFFECTED: " + count);
		} catch (Exception e) {
			e.printStackTrace();
		}finally{
			cstmt.close();  
		}
	}

 

public static void executeUpdateStoredProcedure(Connection con) {  
        try {  
            CallableStatementcstmt = con  
                    .prepareCall("{call dbo.UpdateTestTable(?, ?)}");  
            cstmt.setString(1, "A");  
            cstmt.setInt(2, 100);  
            cstmt.execute();  
            int count = cstmt.getUpdateCount();  
            System.out.println("ROWS AFFECTED: " + count);  
        } catch (Exception e) {  
            e.printStackTrace();  
        }finally{  
            cstmt.close();    
        }  
    }  

附加說明 

 

JDBC調用存儲過程: CallableStatement 

在Java裏面調用存儲過程,寫法那是相當的固定: Class.forName(.... 

Connection conn = DriverManager.getConnection(.... /** 

*p是要調用的存儲過程的名字,存儲過程的4個參數,用4個?號佔位符代替 *其餘地方寫法固定 */ 

CallableStatementcstmt = conn.prepareCall("{call p(?,?,?,?)}"); /** 

*告訴JDBC,這些個參數,哪些是輸出參數,輸出參數的類型用java.sql.Types來指定 

*下面的意思是,第3個?和第4個?是輸出參數,類型是INTEGER的 *Types後面具體寫什麼類型,得看你的存儲過程參數怎麼定義的 

*/ 

cstmt.registerOutParameter(3, Types.INTEGER); cstmt.registerOutParameter(4, Types.INTEGER); /** 

*在我這裏第1個?和第2個?是輸入參數,第3個是輸出參數,第4個既輸入又輸出 

*下面是設置他們的值,第一個設爲3,第二個設爲4,第4個設置爲5 *沒設第3個,因爲它是輸出參數 */ 

cstmt.setInt(1, 3); cstmt.setInt(2, 4); cstmt.setInt(4, 5); //執行 

cstmt.execute(); 

//把第3個參數的值當成int類型拿出來 int three = cstmt.getInt(3); System.out.println(three); 

//把第4個參數的值當成int類型拿出來 int four = cstmt.getInt(4); System.out.println(four); 

//用完別忘給人家關了,後開的先關 cstmt.close(); conn.close(); 

JDBC調用存儲過程,掌握這一個程序足夠了. 

以下是上面程序使用的存儲過程的代碼,我用的是Oracle數據庫,不過不論是什麼數據庫,對於你 

的程序,JDBC這一端寫法都是一樣的. create or replace procedure p 

            (v_a in number,v_bnumber,v_ret out number,v_temp in out number) is begin 

           if(v_a>v_b) then v_ret := v_a;            else v_ret := v_b; 

           end if; v_temp := v_temp + 1; end;

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章