Java.sql.sqLException: Werking niet toegestaan ​​nadat het resultaat is gesloten

Wanneer ik de volgende code uitvoer, krijg ik een uitzondering. Ik denk dat het is omdat ik me voorbereiding op een nieuwe verklaring met hij hetzelfde verbindingsobject. Hoe moet ik dit herschrijven, zodat ik een voorbereide verklaring kan maken en RS2 kan gebruiken? Moet ik een nieuw verbindingsobject maken, zelfs als de verbinding op dezelfde DB is?

   try 
    {
        //Get some stuff
        String name = "";
        String sql = "SELECT `name` FROM `user` WHERE `id` = " + userId + " LIMIT 1;";
        ResultSet rs = statement.executeQuery(sql);
        if(rs.next())
        {
            name = rs.getString("name");
        }
        String sql2 = "SELECT `id` FROM  `profiles` WHERE `id` =" + profId + ";";
        ResultSet rs2 = statement.executeQuery(sql2);
        String updateSql = "INSERT INTO `blah`............"; 
        PreparedStatement pst = (PreparedStatement)connection.prepareStatement(updateSql);    
        while(rs2.next()) 
        { 
            int id = rs2.getInt("id");
            int stuff = getStuff(id);
            pst.setInt(1, stuff);
            pst.addBatch();
        }
        pst.executeBatch();
    } 
    catch (Exception e) 
    {
        e.printStackTrace();
    }
private int getStuff(int id)
{
    try
    {   
            String sql = "SELECT ......;";
            ResultSet rs = statement.executeQuery(sql);
            if(rs.next())
            {
                return rs.getInt("something");
            }
            return -1;
    }//code continues

Antwoord 1, Autoriteit 100%

Het probleem zit hem in de manier waarop je gegevens ophaalt in getStuff(). Elke keer dat u getStuff()bezoekt, krijgt u een nieuwe ResultSet, maar u sluit deze niet.

Dit schendt de verwachting van de klasse Statement(zie hier – http://docs.oracle.com/javase/7/docs/api/java/sql/Statement.html):

Standaard kan er slechts één ResultSet-object per Statement-object tegelijkertijd geopend zijn. Als het lezen van het ene ResultSet-object wordt afgewisseld met het lezen van een ander, moet elk object dus zijn gegenereerd door verschillende Statement-objecten. Alle uitvoeringsmethoden in de Statement-interface sluiten impliciet het huidige ResultSet-object van een statement als er een open bestaat.

Wat het nog erger maakt, zijn de rsuit de oproepcode. Het is ook afgeleid van het veld Statement, maar het is niet gesloten.

Bottom line: u hebt meerdere ResultSetdie betrekking hebben op hetzelfde Statement-object tegelijkertijd geopend.


Antwoord 2, autoriteit 34%

Een ResultSet-object wordt automatisch
gesloten wanneer het Statement-object dat
gegenereerd, wordt het gesloten, opnieuw uitgevoerd,
of gebruikt om het volgende resultaat op te halen
uit een reeks van meerdere resultaten.

Ik vermoed dat je na while(rs2.next())iets probeert te benaderen vanuit rs1. Maar het is al gesloten sinds je de instructie opnieuw hebt uitgevoerd om er rs2 uit te halen. Aangezien je het niet hebt gesloten, denk ik dat het hieronder opnieuw wordt gebruikt.

Other episodes