如何解决ORA-0300:最大打开游标超出异常

时间:2017-05-11 12:02:24

标签: java database oracle jdbc

我有ORA-0300:最大打开游标超出异常

     public void connectionexample(String email)
     {

        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;        
        try {            
            conn = db.getConnection();            
            ps = conn.prepareStatement(select_query);            
            ps.setString(1, email);
            rs = ps.executeQuery();
            if(rs.next()) {
                  ps = conn.prepareStatement(update_query);
                  ps.setString(1, email);                  
                  ps.executeUpdate();                                    
            } else {
                ps = conn.prepareStatement(insert_query);                  
                ps.setString(1, email);
                ps.executeUpdate();             
            }            
        } catch(Exception e) {                    
            LOG.error("Exception occured ", e);                     
        } finally {                    
            DATABASE.release(rs);
            DATABASE.release(ps);
            DATABASE.release(conn);
        }      
    }  

2 个答案:

答案 0 :(得分:2)

您收到此错误,因为您多次使用相同的PrepapredStatement:

ps = conn.prepareStatement(select_query);//<<----------------------Here
...
if (rs.next()) {
    ps = conn.prepareStatement(update_query);//<<-------------------Then here
    ...
} else {
    ps = conn.prepareStatement(insert_query);//<<-------------------or here
    ...
}

要解决您的问题,您必须关闭语句并为新查询创建一个新语句,或者更好的方法是,使用不同的方法分隔操作,每个方法创建并释放其语句和连接。

答案 1 :(得分:1)

您正在重复使用准备好的声明ps

public void connectionexample(String email)
{
  Connection conn = null;
  PreparedStatement ps = null;
  PreparedStatement ps2 = null; -- Use another variable for the second prepared statement
  ResultSet rs = null;        
  try {            
    conn = db.getConnection();            
    ps = conn.prepareStatement(select_query);            
    ps.setString(1, email);
    rs = ps.executeQuery();
    if(rs.next()) {
      ps2 = conn.prepareStatement(update_query); -- Assign this to the second variable
    } else {
      ps2 = conn.prepareStatement(insert_query);                  
    }            
    ps2.setString(1, email);
    ps2.executeUpdate();             
  } catch(Exception e) {                    
    LOG.error("Exception occured ", e);                     
  } finally {                    
    DATABASE.release(rs);
    DATABASE.release(ps);
    DATABASE.release(ps2);  -- Make sure you also close the second prepared statement
    DATABASE.release(conn);
  }
}

但是,您可以使用SQL MERGE statement摆脱对数据库的第二次往返。