Partage
  • Partager sur Facebook
  • Partager sur Twitter

ResultSet closed: je ne trouve pas ou!

java et base de donné

Sujet résolu
    23 mai 2011 à 21:14:02

    Bonjour à tous!

    Je fait un TP sur le java et la base de donnée.
    Toute mes requêtes marchent sauf l'insertion de donnée: ça fonctionne au premier passage dans la boucle et après j'ai cette erreur :
    java.sql.SQLException: Operation not allowed after ResultSet closed.

    J'ai cherché dans mes fonctions et je ne voit pas ce qui peut fermé le resultset.

    Pourriez vous m'aiguiller?
    Merci d'avance!

    /*
     * To change this template, choose Tools | Templates
     * and open the template in the editor.
     */
    package basededonnées;
    
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.ResultSet;
    import java.sql.Statement;
    
    /**
     *
     * @author thibaut
     */
    public class Main
    {
    
    	/**
    	 * @param args the command line arguments
    	 */
    	public static void main (String[] args)
    	{
    		int i = 0;
    		try
    		{
    			Class.forName ("com.mysql.jdbc.Driver").newInstance ();	      // spécification du driver
    			Connection c = DriverManager.getConnection ("jdbc:mysql://localhost/tp10", "root", "");	      //creation de la connexion
    			Statement st = c.createStatement ();	  //creation d'un tube de communication
    
    			/* Requetes de selections */
    
    			ResultSet rs = st.executeQuery ("select * from track where Artist like \"The Beatles\"");	  // requete de selection
    			while (rs.next ())
    			{
    				System.out.println (rs.getString ("Track_Title"));
    			}
    			System.out.println ();
    			rs = st.executeQuery ("select * from cd where SET_ID = 0");	  // requete de selection
    			while (rs.next ())
    			{
    				System.out.println (rs.getString ("Disk_Title"));
    			}
    
    			/* requete de creation, suppression etc...*/
    
    			int n = st.executeUpdate ("CREATE table if not exists Artist (nom VARCHAR (50), id INT)");		  // creation de la table artiste
    
    			System.out.println ();
    			rs = st.executeQuery ("select distinct Artist from track order by Track_ID ");	  // requete de selection
    			while (rs.next ())
    			{
    				System.out.println ("sa rentre ds la boucle");
    				//System.out.println(rs.getString("Artist"));
    				n = st.executeUpdate ("insert into Artist(nom,id) values ('" + rs.getString ("Artist") + "'," + Statement.RETURN_GENERATED_KEYS + ")");
    				System.out.println ("c'est passé");
    				i++;
    			}
    			c.close ();
    
    		} catch (Exception e)
    		{
    			System.out.println ("exception capturée: " + e);
    		}
    	}
    }
    
    • Partager sur Facebook
    • Partager sur Twitter
      24 mai 2011 à 16:24:30

      Tu n'utilises pas bien le Return Generated Keys, qui n'a pas sa place dans la requête SQL.

      De plus, il serait mieux d'utiliser un preparedstatement, pour éviter l'injection sql.

      Quelque chose comme ça :

      PreparedStatement insertion = this.connect.prepareStatement("INSERT INTO Artist VALUES(?,?)", PreparedStatement.RETURN_GENERATED_KEYS);

      (tu remarqueras que la partie ',PreparedStatement.RETURN_GENERATED_KEYS' n'est pas dans les guillemets).

      Ensuite, tu peux faire insertion.setString(1,artistString), ...

      De plus, il me semble très louche que tu fixes toi même l'id. Tu n'utilises pas un index automatique ?

      Bonne chance !
      • Partager sur Facebook
      • Partager sur Twitter
        24 mai 2011 à 23:34:50

        Tu as l'air de t'y connaître, et moi je débute en bd et java mélangé, donc pourrais tu m'expliquer quel est la différence entre un preparedStatement un et statement?

        Quand à mon problème il est résolut grâce à un camarade qui utilise un deuxième statement pour la requête d'insertion, et apparemment ça fonctionne.
        Enfin Le return_generated_key ... ben c’était du tâtonnement, justement je cherchait un moyen de mettre un id auto-incrémenté autrement qu'en passant un variable i qui s’incrémentait à chaque tour de boucle.
        • Partager sur Facebook
        • Partager sur Twitter
          25 mai 2011 à 9:06:09

          PreparedStatement est une sous-classe de Statement qui permet de spécifier la partie variable de ta requête après avoir écrit celle-ci.

          Ca permet :
          -de pas se casser le *** avec des ' et des " partout, et de rendre le code lisible.
          - d'éviter toute forme d'injection sql via des string malicieuses.

          Je ne peux que te conseiller (si tu n'es pas allergique à l'anglais) de lire la doc fourni par sun :-)

          Pour l'id autoincrémenté, il faut que tu règles ca dans la config de ta base de données. Avec mysql+phpmyadmin par exemple, lorsque tu crées une colonne sur la table, tu peux cocher la case "AUTO_INCREMENT".

          Je t'accorde que le return generated keys a pas une doc très claire, mais avec l'exemple que je t'ai donné, tu devrais t'en sortir. N'oublie qu'il ne marche que pour des executeQuery, pas des executeUpdtae.
          • Partager sur Facebook
          • Partager sur Twitter
            25 mai 2011 à 16:36:21

            Merci pour tes réponses!

            Je me suis renseigné sur les injection SQL c'est vrai que ça peut etre un probleme, mais dans un TP decouverte je ne pense pas que ce soit essentiel de s'en proteger, mais au moins je saurais comment m'en proteger grace a toi ^^.

            Non je ne suis pas allergique à l'anglais, je n'avais juste pas prit le temps d'aller voir la doc exacte.

            En tout cas merci pour tes réponses!
            • Partager sur Facebook
            • Partager sur Twitter

            ResultSet closed: je ne trouve pas ou!

            × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
            × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
            • Editeur
            • Markdown