昨天工作的时候,在调用一下存储过程的时候,出现了一个问题,那就是,这个存储过程返回两个结果集,即在存储过程的最后,类似这样的语句:
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()方法,那么这些驱动有两种可能,一种是实现自己的读取方法,二是针对数据库自身的特性,进行了效率上的提高.
呵,这就没有时间再去仔细的研究了..