JDBC执行存储过程得到多结果集

来源:互联网 发布:linux下需要安装哪些库 编辑:程序博客网 时间:2024/06/05 09:46

转自: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()方法,那么这些驱动有两种可能,一种是实现自己的读取方法,二是针对数据库自身的特性,进行了效率上的提高.

呵,这就没有时间再去仔细的研究了..


0 0