IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

JDBC Java Discussion :

Erreur "Operation not allowed after ResultSet closed"


Sujet :

JDBC Java

  1. #1
    Membre du Club
    Inscrit en
    Octobre 2011
    Messages
    119
    Détails du profil
    Informations forums :
    Inscription : Octobre 2011
    Messages : 119
    Points : 42
    Points
    42
    Par défaut Erreur "Operation not allowed after ResultSet closed"
    bonsoir
    l'erreur suivante s'affiche en exécutant mon prg tandis que j'ai pas fermé mon resultSet mais je n'arrive pas à comprendre pourquoi cela. voici un bout de code qui cause l'erreur:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     String queryString=("SELECT idPage, count(idPageAmi) AS nbreAmis FROM connectivite GROUP BY idPage");
       resultat = statement.executeQuery(queryString);
       while(resultat.next()){
     
    	 System.out.println(resultat.getInt("idPage"));
    	 System.out.println(resultat.getInt("nbreAmis"));
    	   String query=("UPDATE connectivite SET nbreAmis ="+  resultat.getInt("nbreAmis")+" WHERE idPage="+ resultat.getInt("idPage"));
    	     System.out.println(query);
    	   statement.executeUpdate(query);
     
       }
     
            }

  2. #2
    Membre du Club
    Inscrit en
    Octobre 2011
    Messages
    119
    Détails du profil
    Informations forums :
    Inscription : Octobre 2011
    Messages : 119
    Points : 42
    Points
    42
    Par défaut
    apparemment le pb est du à la requête update qui est à l’intérieur de while car si j'élimine cette instruction et je fais un simple affichage l'erreur n'est plus affichée. mais le pb que j'ai besoin de la requete update comment résoudre ça s'il vous plait?

  3. #3
    in
    in est déconnecté
    Membre expérimenté Avatar de in
    Profil pro
    Inscrit en
    Avril 2003
    Messages
    1 612
    Détails du profil
    Informations personnelles :
    Localisation : France, Finistère (Bretagne)

    Informations forums :
    Inscription : Avril 2003
    Messages : 1 612
    Points : 1 718
    Points
    1 718
    Par défaut
    tu as l'erreur car en effet, tu utilises ton statement dans la boucle alors qu'il est déjà en cours d'utilisation. Le statement.executeUpdate(query); doit passer le premier coup puis le next() sort en erreur car le statement a été fermé.

    Pour résoudre le problème, il te suffit d'utiliser 2 objets statement différents.
    Par contre, ça n'est pas très joli ...
    Et surtout n'oublie pas de fermer tes resultset et statements après utilisation dans un bloc finally (cf la FAQ)
    "If email had been around before the telephone was invented, people would have said, 'Hey, forget email! With this new telephone invention I can actually talk to people!"

    Besoin d'une nouvelle méthode pour développer ? -> http://www.la-rache.com/

  4. #4
    Nouveau Candidat au Club
    Homme Profil pro
    Architecte de système d'information
    Inscrit en
    Janvier 2012
    Messages
    1
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Architecte de système d'information

    Informations forums :
    Inscription : Janvier 2012
    Messages : 1
    Points : 1
    Points
    1
    Par défaut Remplacer SELECT et UPDATE avec MERGE
    Je crois qu'il serait mieux, au lieu d'avoir une instruction SQL SELECT suivi d'un boucle d'instructions UPDATE, metre q'une instruction SQL MERGE, comme celui-ci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    MERGE INTO connectivite x
    USING (SELECT idPage, count(idPageAmi) AS nbreAmis FROM connectivite GROUP BY idPage) y
    ON (y.idPage = x.idPage)
    WHEN MATCHED THEN
    UPDATE SET nbreAmis = y.nbreAmis
    C'est un peu plus compliqué du point de vue de la sophistication en SQL, c'est vrai, mais cela simplifie le code Java et ameliore la performance de la base de données.
    Voici un document sur l'instruction MERGE:
    http://docs.oracle.com/cd/B19306_01/...ments_9016.htm

    Le livre suivant aussi peut être interesant: 'Java Web Database Application Development' á: http://javawebdb.com

  5. #5
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    Le mieux ca reste de faire tout ça en une seule opération. Il est dans 99.9% des cas inutile et contre performant de faire un select d'itérer dessus et, pour chaque row lu, de mettre à jour une base de données. Le language SQL permet de faire tout ça en une seule passe!

    Ceci devrais faire l'affaire (je suis un peu rouillé en sql) et éviter le ping-pong réseau.
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    UPDATE connectivite c SET c.nbreAmis = (SELECT count(idPageAmi)  FROM connectivite c2 where c2.idPage = c.idPage)

    edit: le MERGE est effectivement probablement plus performant, pas vu

  6. #6
    Membre du Club
    Inscrit en
    Octobre 2011
    Messages
    119
    Détails du profil
    Informations forums :
    Inscription : Octobre 2011
    Messages : 119
    Points : 42
    Points
    42
    Par défaut
    bonjour

    moi j'ai déjà résolu mon pb à l'aide du conseil présenté par in mais je ne comprends pas ce que HowardHyde a dit et concernant la solution de tchize_
    j'ai compris mais ce que je comprends pas pourquoi vous me proposez d'autres solutions est ce que la première solution proposé par in n'est pas juste ?

  7. #7
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    Imaginons que t'ais 100.000 lignes, correspondant à disons 5000 pages. Tu va construire, interpréter et exécuté dans la transaction 5001 requetes updates. alors qu'en faisant tout en une seule requete SQL, tu va n'avoir qu'une requete. Si le serveur met 200ms / requete, c'est la différence entre une opération qui se fera en 2 secondes et une opération qui se fera en 15 minutes. Sans compter que l'opération avec 5000 aller / retour va bien charger ton réseau et ton SGBD.

    Bref, SQL est un language, utilisez le comme tel.

  8. #8
    Membre du Club
    Inscrit en
    Octobre 2011
    Messages
    119
    Détails du profil
    Informations forums :
    Inscription : Octobre 2011
    Messages : 119
    Points : 42
    Points
    42
    Par défaut
    merci pour l'explication mais quand je mets la requete que tu m'as proposé l'erreur suivante est affichée:You can't specify target table 'c' for update in FROM clause

  9. #9
    in
    in est déconnecté
    Membre expérimenté Avatar de in
    Profil pro
    Inscrit en
    Avril 2003
    Messages
    1 612
    Détails du profil
    Informations personnelles :
    Localisation : France, Finistère (Bretagne)

    Informations forums :
    Inscription : Avril 2003
    Messages : 1 612
    Points : 1 718
    Points
    1 718
    Par défaut
    Citation Envoyé par boubounagh Voir le message
    ... est ce que la première solution proposé par in n'est pas juste ?
    Ben c'était pas faux, , mais effectivement je n'ai pas fait attention à ce que tu voulais faire ...

    C'est beaucoup mieux de faire ça en une seule requête. Le Merge est plus performant mais s'il te fait peur pour la maintenance, utilise l'update simple.

    Citation Envoyé par boubounagh Voir le message
    You can't specify target table 'c' for update in FROM clause
    Tu as dû mal recopier la solution de tchize_. Il te manques sûrement un 2
    Tu ne peux pas faire un select sur la table que tu update.
    "If email had been around before the telephone was invented, people would have said, 'Hey, forget email! With this new telephone invention I can actually talk to people!"

    Besoin d'une nouvelle méthode pour développer ? -> http://www.la-rache.com/

  10. #10
    Membre du Club
    Inscrit en
    Octobre 2011
    Messages
    119
    Détails du profil
    Informations forums :
    Inscription : Octobre 2011
    Messages : 119
    Points : 42
    Points
    42
    Par défaut
    Tu as dû mal recopier la solution de tchize_. Il te manques sûrement un 2

    en fait je suis sur que j'ai bien copié le code de tchize.

    Tu ne peux pas faire un select sur la table que tu update.

    selon la recherche que j'ai effectué concernant l'erreur affiché la cause de cet erreur est comme vous m'avez dit on ne peut pas faire un select dans un update donc la requete apparemment n'est pas totalement correcte.

  11. #11
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    J'ai exécuté le code que je t'ai donné ici, sans aucun problème:
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    UPDATE connectivite c SET c.nbreamis = (SELECT count(idPageAmi)  FROM connectivite c2 WHERE c2.idPage = c.idPage)

    Résultat:
    Code x : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    "NBREAMIS"                    "IDPAGEAMI"                   "IDPAGE"                      
    "4"                           "aa"                          "a"                           
    "4"                           "bb"                          "a"                           
    "4"                           "cc"                          "a"                           
    "4"                           "dd"                          "a"                           
    "3"                           "aa"                          "b"                           
    "3"                           "bb"                          "b"                           
    "3"                           "cc"                          "b"                           
    "1"                           "cc"                          "c"                           
    "1"                           "aa"                          "d"                           
    "2"                           "bb"                          "e"                           
    "2"                           "cc"                          "e"                           
    "3"                           "aa"                          "f"                           
    "3"                           "bb"                          "f"                           
    "3"                           "cc"                          "f"

  12. #12
    Membre du Club
    Inscrit en
    Octobre 2011
    Messages
    119
    Détails du profil
    Informations forums :
    Inscription : Octobre 2011
    Messages : 119
    Points : 42
    Points
    42
    Par défaut
    c'est bizarre mais la meme erreur est affiché :You can't specify target table 'c' for update in FROM clause
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     String query=("UPDATE connectivite c SET c.nbreamis = (SELECT count(idPageAmi)  FROM connectivite c2 WHERE c2.idPage = c.idPage)");
    	 System.out.println(query);
    	  statement2.executeUpdate(query);
    je ne sais pas mais normalement je fais copier coller pour la meme requete proposé par tchize mais l'erreur est encore affiché lors de l'exécution.

  13. #13
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    C'est peut etre ton SGDB qui refuse ça (limitation), j'ai testé sur oracle. Maintenant, essaie la version merge qui t'es fournie plus haut.

  14. #14
    Membre du Club
    Inscrit en
    Octobre 2011
    Messages
    119
    Détails du profil
    Informations forums :
    Inscription : Octobre 2011
    Messages : 119
    Points : 42
    Points
    42
    Par défaut
    s'il vous plait si c'est possible vous pouvez m'expliquer un peu la requete merge
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    USING (SELECT idPage, count(idPageAmi) AS nbreAmis FROM connectivite GROUP BY idPage) y // y ici qu'est qu'elle signifie  quel son role

  15. #15
    Membre du Club
    Inscrit en
    Octobre 2011
    Messages
    119
    Détails du profil
    Informations forums :
    Inscription : Octobre 2011
    Messages : 119
    Points : 42
    Points
    42
    Par défaut
    une autre remarque peut etre importante que moi je travaille avec mysql et non pas oracle et quand j'écris cette requete une erreur s'affiche indiquant:

    You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'MERGE INTO connectivite x USING (SELECT idPage, count(idPageAmi) AS nbreAmis FRO' at line 1

  16. #16
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    Mysql ne supporte pas les updates combines à un select sur la même table. Et le mot clé MERGE n'est pas supporté non plus :s

    Donc je vous recommanderais de créer une table temporaire avec le select, puis de faire l'update. Ca ne fait que deux requetes et les tables temporaires sont rapides.

    Maintenant, d'une manière plus basique, je trouve curieux votre structure de donnée Stocker le nombre d'amis sur la même row que "un amis" ca fait quand même une sacré duplication de données.

  17. #17
    Membre du Club
    Inscrit en
    Octobre 2011
    Messages
    119
    Détails du profil
    Informations forums :
    Inscription : Octobre 2011
    Messages : 119
    Points : 42
    Points
    42
    Par défaut
    Donc je vous recommanderais de créer une table temporaire avec le select, puis de faire l'update. Ca ne fait que deux requetes et les tables temporaires sont rapides.
    ce que vous conseillez de faire normalement ce que j'ai déjà fait avec deux statement
    Maintenant, d'une manière plus basique, je trouve curieux votre structure de donnée Stocker le nombre d'amis sur la même row que "un amis" ca fait quand même une sacré duplication de données.
    peut etre vous avez raison mais moi j'ai pensé que dans ma table connectivite j'ai l'idPageFacebook, idPageAmi et le nombre d'amis de cette page mais le nbre d'amis se répète pour chaque idPageAmi.

  18. #18
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    JE recommenderais soit de stocker le nombre d'amis dans une table séparé (solution la plus performante mais nécessite de la maintenance) ou de calculer simplement cette information via un group by à chaque fois que vous en avez besoin (un peu moins performant mais devrais être rapide à calculer avec un index sur la colonne).

  19. #19
    Membre du Club
    Inscrit en
    Octobre 2011
    Messages
    119
    Détails du profil
    Informations forums :
    Inscription : Octobre 2011
    Messages : 119
    Points : 42
    Points
    42
    Par défaut
    merci pour tout les conseils que vous m'avez donné mais honnêtement je veux revenir à la première solution proposé peut etre elle n'est pas très performante mais ça la plus simple à mon avis.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 5
    Dernier message: 26/03/2013, 10h55
  2. Operation not allowed after ResultSet closed
    Par menakikou dans le forum Débuter
    Réponses: 1
    Dernier message: 22/09/2009, 16h38
  3. SQLexception: Operation not allowed after ResultSet closed
    Par fripette dans le forum Servlets/JSP
    Réponses: 8
    Dernier message: 12/06/2008, 09h58
  4. Operation not allowed after ResultSet closed
    Par Smix007 dans le forum JDBC
    Réponses: 3
    Dernier message: 10/03/2008, 17h28
  5. Réponses: 7
    Dernier message: 11/08/2006, 09h24

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo