JDBC執行存儲過程得到多結果集

轉自:http://blog.csdn.net/it_man/article/details/745751


昨天工作的時候,在調用一下存儲過程的時候,出現了一個問題,那就是,這個存儲過程返回兩個結果集,即在存儲過程的最後,類似這樣的語句:
select #proctmp.id, #proctmp.proc_id, #proctmp.proc_name, #proctmp.sp_name from #proctmp
select #privtmp.id, #privtmp.id_type, #privtmp.serv_if_op_id, #privtmp.serv_if_op_name from #privtmp

那怎麼去接收這樣的一個執行結果呢?

在網上找,確實不知道用什麼關鍵字去搜索,用幾個關鍵字去搜索,得到的結果都無關緊要,
於是就給一些朋友問,幸好,他曾經處理過這樣的情況,給了一個oracle的例子.
如下:

  java.sql.CallableStatement stmt = null;
  java.sql.ResultSet rset = null;

  String callSQL =
   "{ call KK_Srv_Apply.SelectApplyCursor( ?, ?, ?, ?, ?, ?, ? ) }";

  try
  {
   stmt = m_conn.prepareCall(callSQL);

   stmt.setString( 1, m_SysUserCode);
   stmt.setInt( 2, m_CurrPage  );
      .............................

   stmt.execute();

   rset = (ResultSet) ((OracleCallableStatement) stmt).getCursor(2);
   while (rset.next()){
      .............
   }

  catch (SQLException ex)
  {
   logger.info( "" );
   ex.printStackTrace(System.out);
  }
  catch (Exception ex)
  {
   logger.info( "" );
   ex.printStackTrace(System.out);
  }
  finally
  {
   try
   {
    if (stmt != null)
     stmt.close();
   }
   catch (SQLException see)
   {
    
   }
  }
  
  return;
 }

從例子中可以看出來,執行一個存儲過程,得到的也是一個結果集,便這個結果集是複合的,即這是許多結果集的"數組",rset = (ResultSet) ((OracleCallableStatement) stmt).getCursor(2);就是得到遊標指向第二個的結果集,,,然後就可以以"正常"的方式來進行操作了.

 

現在問題又來了,即,我操作的是Sybase數據,這會不會和Oracle都支持這種存取呢?

查了一個Sybase的JDBC驅動文檔,發現,它不這兩個類
com.sybase.jdbc2.jdbc.SybCallableStatement ;
com.sybase.jdbc2.jdbc.SybCursorResultSet ;
com.sybase.jdbcx.SybCallableStatement;
com.sybase.jdbcx.SybCursorResultSet;

那麼,可以想象的到,這應該也處理這樣的結果的,
我是如下處理的:
try{
  String sql = "{ call sp_select_role_priv ( ? ) } " ;

  dbm = DBConnectionPool.getInstance();
  conn = dbm.getConnection(Constants.DB_earn) ;
  cstmt = (SybCallableStatement) conn.prepareCall(sql) ;
  java.sql.ResultSet rset = null ; //得到的結果集
  java.sql.ResultSet rs = null ; //小結果集

   do{
     rs = cstmt.getResultSet() ;
     System.out.println("## resultSet:"+k);
     while (rs.next()) {
     if(k==1){
     if(rs.getInt(1)<1){
     continue;
     }
     }
     if(k==2){
     if(rs.getInt(1)<0){ //1:具有權限
     continue;
     }
     }
     }
     rs.close() ;
     k++;
  }while (cstmt.getMoreResults());

      }catch (SQLException ex) {
         ex.printStackTrace() ;
      }
      finally {
   ........
   }

結果執行,成功的將問題解決.sybase和oracle有所不同的是,
它取得第幾個結果集的時候是通過rs = cstmt.getResultSet()得到的,
在得到這個結果集這前,需要將遊標指到應該得到的地方,可以通過cstmt.getMoreResults(int i)得到,也可以以次取,通過cstmt.getMoreResults()將遊標指向下一個結果集.

另外,自己又看了一下java.sql包中的類,和SybCallableStatement,發現,直接調用java.sql包的中CallableStatement,也有getMoreResults()方法,那麼這些驅動有兩種可能,一種是實現自己的讀取方法,二是針對數據庫自身的特性,進行了效率上的提高.

呵,這就沒有時間再去仔細的研究了..


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