返回CURSOR类型的,我见过有人用以下方法
ResultSet rs = null; 
int updateCount = -1; 
flag = cs.execute(); 
do{ 
    updateCount = cs.getUpdateCount(); 
    if(updateCount != -1){//说明当前行是一个更新计数 
        //处理. 
        cs.getMoreResults(); 
        continue;//已经是更新计数了,处理完成后应该移动到下一行 
             //不再判断是否是ResultSet 
    } 
    rs = cs.getResultSet(); 
    if(rs != null){//如果到了这里,说明updateCount == -1 
        //处理rs 
        cs.getMoreResults(); 
        continue; 
            //是结果集,处理完成后应该移动到下一行 
    } 
    //如果到了这里,说明updateCount == -1 && rs == null,什么也没的了 
    
}while(!(updateCount == -1 && rs == null)); 
------------------------------------------------
我是一直用oracler的,用(ResultSet)CallableStatement.getObject(1)没问题
手头没用SQLSERVER,上面程序供你参考

解决方案 »

  1.   

    还是不行, 明明拿到了 ResultSet , 就是说这个错 ojbect has been closed 
    而且通过stmt.getMetaData 方法, 查看到 ResultSet 的metadata 也确是我想要的结果. 为什么就不给我呢????
      

  2.   


    声明
    private CallableStatement sqlSend;
    sqlSend = remoteConn.prepareCall("{ call " + dataUser + ".proGroupsms1(?,?,?,?,?,?,?,?,?) }");执行
    try{
    sqlSend.setString(1,sendSms.sp_num);
    sqlSend.setString(2,sendSms.dst_num);
    sqlSend.setString(3,sendSms.busi_code);
    sqlSend.setByte(4,sendSms.msg_code);
    sqlSend.setString(5,sendSms.content);
    sqlSend.setString(6,sendSms.reserve);
    sqlSend.registerOutParameter(7,java.sql.Types.INTEGER);
    sqlSend.setString(8,NewClient.spNum);
    sqlSend.setString(9,sendSms.msgid);
    sqlSend.executeUpdate();
    remoteConn.commit();

    errSms = new ErrorSMS();
    errSms.msg_id = sendSms.msg_id;
    errSms.err_code = (byte)sqlSend.getInt(7);
    if (NewClient.in_debug == 1)
    System.out.println("[RemoteDBThread]Put a RetCode:" + errSms.err_code);
    errSms = (ErrorSMS)merrQueue.writeNoWait(errSms);

    sendSms = (SendSMS)msendQueue.read(sendSms);
    }catch(Exception e){
    e.printStackTrace();
    System.out.println("[RemoteDBThread]发送短信过程出错,跳过......");
    remoteConn.rollback();
    sendSms = (SendSMS)msendQueue.read(sendSms);
    }
      

  3.   

    声明
    private CallableStatement sqlSend;
    sqlSend = remoteConn.prepareCall("{ call " + dataUser + ".proGroupsms1(?,?,?,?,?,?,?,?,?) }");执行
    try{
        sqlSend.setString(1,sendSms.sp_num);
        sqlSend.setString(2,sendSms.dst_num);
        sqlSend.setString(3,sendSms.busi_code);
        sqlSend.setByte(4,sendSms.msg_code);
        sqlSend.setString(5,sendSms.content);
        sqlSend.setString(6,sendSms.reserve);
        sqlSend.registerOutParameter(7,java.sql.Types.INTEGER);
        sqlSend.setString(8,NewClient.spNum);
        sqlSend.setString(9,sendSms.msgid);
        sqlSend.executeUpdate();
        remoteConn.commit();
        errSms = new ErrorSMS();
        errSms.msg_id = sendSms.msg_id;
        errSms.err_code = (byte)sqlSend.getInt(7);
        if (NewClient.in_debug == 1)
        System.out.println("[RemoteDBThread]Put a RetCode:" + errSms.err_code);
        errSms = (ErrorSMS)merrQueue.writeNoWait(errSms);
        sendSms = (SendSMS)msendQueue.read(sendSms);
     }catch(Exception e){
        e.printStackTrace();
        System.out.println("[RemoteDBThread]发送短信过程出错,跳过......");
        remoteConn.rollback();
        sendSms = (SendSMS)msendQueue.read(sendSms);
     }
    这是JAVA调用ORACLE存储过程非常好用安全的程序段,不知道是不是有用!
      

  4.   

    我试了一下,上面的程序是可用的,只是有个小问题
    以下是我的测试程序:
    public class sqltest { /**
     * @param args
     */
    public static void main(String[] args) {
    // TODO Auto-generated method stub
    try{
    Connection conn;
    Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
    conn=DriverManager.getConnection("jdbc:odbc:Driver={SQL Server};Server=vpc98;uid=sa;pwd=;Database=master");
    String sql="";
    Statement st=conn.createStatement();
    ResultSet rs;
    /* sql="select * from test";
    rs=st.executeQuery(sql);
    while (rs.next())
    {
    String id=rs.getString("postcode");
    System.out.println(id);
    }
    if (rs!=null) rs.close();
    */
    CallableStatement cs = conn.prepareCall("dbo.sp_tables");
    rs = null; 
    int updateCount = -1; 
    boolean flag = cs.execute(); 
    do{ 
        updateCount = cs.getUpdateCount(); 
        if(updateCount != -1){//说明当前行是一个更新计数 
            //处理. 
            cs.getMoreResults(); 
            System.out.println(updateCount);
            continue;//已经是更新计数了,处理完成后应该移动到下一行 
                 //不再判断是否是ResultSet 
        } 
        rs = cs.getResultSet(); 
        if(rs != null){//如果到了这里,说明updateCount == -1 
            //处理rs 
         System.out.println("ok");
         while (rs.next())
    {
       String id=rs.getString("table_name");
       System.out.println(id);
    }
         rs.close();
         rs = null;
            //cs.getMoreResults(); 
            continue; 
                //是结果集,处理完成后应该移动到下一行 
        } 
        //如果到了这里,说明updateCount == -1 && rs == null,什么也没的了 
        
    }while(!(updateCount == -1 && rs == null)); 

    if (st!=null)st.close();
    if (conn!=null) conn.close();
    }
    catch(Exception e){
    System.out.println(e.toString());
    } }}
    我是以系统的sp_tables过程作为测试的,它的返回就是一个记录集
    不过我不知如果是在参数中返回是否可以(sp_tables是在结果中返回的),因为我对SQL Server不熟
    楼主可再试一下你的存储过程是否可用
    另外,楼上的是用oracle,我上面提过oracle用(ResultSet)CallableStatement.getObject(1)是肯定可以的,我就这样用过
      

  5.   

    谢谢楼上热心的朋友.
    我已经找到问题的答案了.
    如果存储过程返回结果集, 并且同时还有输出参数的话, 在java里面应该使用完结果集, 再使用getXXX(parameterIndex)这样的方法获取输出参数, 因为每当使用getXXX系列方法获取输出参数时,jdbc会自动关闭结果集......残念呀......在jdk文档里关于CallableStatement接口的说明有这样一段话,再明白不过了:For maximum portability, a call's ResultSet objects and update counts should be processed prior to getting the values of output parameters. 
    谢谢上面热心参与的朋友,本贴保留至今晚(2005-09-22),到时将结贴散分.