轉自: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()方法,那麼這些驅動有兩種可能,一種是實現自己的讀取方法,二是針對數據庫自身的特性,進行了效率上的提高.
呵,這就沒有時間再去仔細的研究了..