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

Servlets/JSP Java Discussion :

fonction recursive d'affichage avec requete inside


Sujet :

Servlets/JSP Java

  1. #1
    Membre confirmé
    Inscrit en
    Juin 2005
    Messages
    110
    Détails du profil
    Informations personnelles :
    Âge : 45

    Informations forums :
    Inscription : Juin 2005
    Messages : 110
    Par défaut fonction recursive d'affichage avec requete inside
    Bonjour,

    j'ai une table dans laquelle sont stockee des categories liees entre elle par une cle etrangere report_id.
    Je precise tout de suite que je seche aussi sur une solution SQL pure a ce probleme par l'utilisation de ON CASCADE DELETE, mais je n'arrive pas. j'utilise MySQL.

    Donc ma premiere idee etait une fonction jsp. J'ai deja ecrit une fonction recursive de parcours de ma table qui me cree un menu dynamique et qui fonction tres bien. Je me suis donc inspire de ce code pour ecrire celle-ci qui est a priori plus simple. Mais apres avoir ecrit 3-4 versions differentes la je seche sur le meme message d'erreur depuis des heures, voci mes codes:

    page jsp:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
        <%  
            //get session variables
            int par = 0;
            int lev = 0;
            String strParent = session.getAttribute("S_Parent").toString();
            String strLevel = session.getAttribute("S_Level").toString();
            par = Integer.parseInt(strParent);
            lev = Integer.parseInt(strLevel);
            
            // other variables
            String name = "";
            String sql = "";
            int n=0;
            int i=0;
     
            // get all the lines at that level
            rs = statement.executeQuery("SELECT * FROM REPORT WHERE REPORT_PARENT=" + par + " AND REPORT_LEVEL=" + lev + " ORDER BY REPORT_ID");
            
            // for each
            while (rs.next()){
                i++;             
                int id = rs.getInt(1);
                name = rs.getString(2);
                
                String S_Nom = "chk" + i;
                String str = session.getAttribute(S_Nom).toString();
                
                // was the report checked ?
                if (str.compareTo("no")!=0){
                    
                    out.println("report checked :" + name + "<br>");
                    
                    // deleting of the first entity
                    sql= sql.concat("DELETE FROM REPORT WHERE REPORT_ID='" + id + "';");
                    //statement.executeUpdate(sql);
     
                    // is it a category ?
                    
                    if (rs.getString(4).compareTo("Y")==0){
                        Menu m = new Menu();
                        out.println("prepare to enter function <br>");
                        sql =sql.concat(m.deleteCascade(connection, statement, id));
                    }     
                }
            }
            
            rs.close();
            out.println("<br>sql : " + sql);
          
        %>
    et fonction java :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    public String deleteCascade(Connection conn, Statement st, int parent)throws IOException {
     
        String response = new String("<br>debut : " + parent + "<br>");
        String sql = new String("");
        String hs="";
        int dad = 0;
        int n = 0;
     
        try{    
            sql = "SELECT * FROM REPORT WHERE REPORT_PARENT='" + parent + "' order by REPORT_ID";
            ResultSet rs = null;
            rs = st.executeQuery(sql);
     
            // resultset exploration
            while (rs.next()){
                // we need to memorize the row in the resultset
                n = rs.getRow();
                hs =rs.getString(4);
                dad=rs.getInt(1);
     
                response = response.concat("DELETE FROM REPORT WHERE REPORT_PARENT='" + dad + "';");
     
                // if the report has kids, it's a label, we print the name and make a sub menu 
                // by recalling the function with the new data
                if(hs.compareTo("Y")==0){
                    Menu m = new Menu();
                    dad = rs.getInt(1);
     
                    // recursive call of the function
                    response = response.concat(m.deleteCascade(conn, st,dad)); 
     
                    // the resultset being closed in the call of the function, we have to recreate it
                    rs = st.executeQuery(sql);
                    for(int d=1; d<=n; d++){
                        rs.next();
                    }            
                }
            }
            rs.close();
        }
        catch (SQLException E){
            System.err.println(E.getMessage());
            response = response.concat(E.getMessage());
        }
     
        return response;
    }
    Dans cette derniere version je ne fais plus de delete dans la fonction, je copie les requetes dans une chaine de caracteres que je renvoie.

    L'execution genere une exception a l'entre du try, due a la requete. Et le message d'erreur est le suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Operation not allowed after ResultSet closed
    An SQL exception occured.
    Sauf que je n'ai ferme aucun resultSet a ce moment la.

    Merci

  2. #2
    Inactif  
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    2 189
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : Suisse

    Informations forums :
    Inscription : Mai 2006
    Messages : 2 189
    Par défaut
    petite idée mais pas du tout certain que ca marche, et si tu sors ton resultSet de ton try / catch et que tu le close dans le finally ?

  3. #3
    Membre confirmé
    Inscrit en
    Juin 2005
    Messages
    110
    Détails du profil
    Informations personnelles :
    Âge : 45

    Informations forums :
    Inscription : Juin 2005
    Messages : 110
    Par défaut
    merci Alex pour ta proposition, je n'ai pas essaye car g finalement resolu le pb apres une bonne nuit de sommeil en ne declarant pas un nouveau resultSet dans la fonction et en le mettant en parametre, comme ca j'utilise toujours le meme c sur et je le remet a jour des que j'ai besoin.

    Mais j'ai un nouveau probleme. Ma fonction envoie donc maitenant une chaine de caracteres. Cette chaine est simplement l'enchainement des requetes SQL delete separees par des ';'.
    A priori quand je mets une requete de ce type dans MySQL en direct ca fonctionne tres bien. Mais la avec JDBC ca ne fonctionne pas appramment. Donc la je dois extraire mes requetes pour les executer une a une. Deja j'ai eu du mal a faire ca mais en plus j'ai un message d'erreur 'index out of range provoque par la fonction substring et je ne comprends pas pourquoi. J'ai fait l'exe sur papier plusieurs fois et je ne vois pas ou est l'erreur.
    C tres bizarre il me fait une erreur qund j'additionne deux int.
    begin = begin +2; c ok
    begin = begin + len; pas ok
    Voici mon code, j'espere que qq'un saura m'expliquer cette erreur.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
            sql=sql.concat("requete1;requete2;requete3;/");
            cpt=0;
            int begin = 0;
            int len = 0; 
            String req="";
            char[] ch =sql.toCharArray();
            cpt=0;
            req="";
     
            while (ch[cpt]!='/'){
                req="";
                // searching a request
                while (ch[cpt]!=';'){
                    cpt++;
                }
                req = sql.substring(begin, cpt);
                out.println(req);
                begin = begin+cpt;
                begin++;
                cpt++;
            }
     
            out.println("<br>sql : " + sql);
            rs.close();
    Merci

  4. #4
    Modérateur
    Avatar de OButterlin
    Homme Profil pro
    Inscrit en
    Novembre 2006
    Messages
    7 313
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 7 313
    Billets dans le blog
    1
    Par défaut
    Pour ton problème initial, il vient du fait que tu passes le statement à ta fonction récursive.
    Le fait de réexécuter le statement ferme le resultSet précédent, donc ton erreur "Operation not allowed after ResultSet closed
    An SQL exception occured." est normale, tu l'as effectivement fermé (implicitement).

    A vrai dire, il faudrait recréer un statement dans la fonction récursive via la connexion que tu passes.
    Bien sûr, à la fin de ta fonction récursive, tu fais un statement.close() (de préférence dans un bloc try catch finally) sinon tu risques de dépasser le nombre maximum de statements d'une connexion (ce nombre est variable)...

    Tu pourrais avantageusement passer un preparedStatement pour le delete à la fonction récursive.
    ça se créé comme ceci :
    PreparedStatement pstmt = connection.preparedStatement("DELETE FROM REPORT WHERE REPORT_PARENT=?");

    ensuite, il suffit de passer le paramètre comme ça : pstmt.setInt(1, valeur);
    puis pstmt.execute();

    Voila, j'espère que ça t'aidera...

    A+
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  5. #5
    Membre confirmé
    Inscrit en
    Juin 2005
    Messages
    110
    Détails du profil
    Informations personnelles :
    Âge : 45

    Informations forums :
    Inscription : Juin 2005
    Messages : 110
    Par défaut
    merci pour les info, j'ai resolu ce probleme comme je disais en passant le resultset en parametre.
    Mais interessant ton preparerStatement, c en gros un statement qui contient la requete c ca ?

    Sinon personne pour mon deuxieme probleme ?

    Merci !

  6. #6
    Modérateur
    Avatar de OButterlin
    Homme Profil pro
    Inscrit en
    Novembre 2006
    Messages
    7 313
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 7 313
    Billets dans le blog
    1
    Par défaut
    Pour ton deuxième problème, tu te compliques pas mal la vie...

    En gardant le principe d'une chaîne de caractères contenant les requêtes sql, séparées par ";" :
    - oublie le "/" de fin
    - utilise StringTokenizer token = new StringTokenizer( taChaîne, ";" );

    ensuite

    Statement stmt = connection.createStatement();
    while ( token.hasMoreElements() )
    {
    stmt.executeUpdate( token.nextToken() );
    }

    Tu peux aussi utiliser la commande stmt.addBatch( token.nextToken() );
    et à la fin de ta boucle stmt.executeBatch();

    A+
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  7. #7
    Membre confirmé
    Inscrit en
    Juin 2005
    Messages
    110
    Détails du profil
    Informations personnelles :
    Âge : 45

    Informations forums :
    Inscription : Juin 2005
    Messages : 110
    Par défaut
    ca marche nickel merci beaucoup !

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

Discussions similaires

  1. [MySQL] probleme affichage avec requete sql
    Par kate59 dans le forum PHP & Base de données
    Réponses: 5
    Dernier message: 23/06/2015, 13h43
  2. Pb d'affichage avec requete SQL!
    Par papy75 dans le forum Requêtes et SQL.
    Réponses: 13
    Dernier message: 24/03/2008, 03h49
  3. [MySQL] requete de mise a jour dans fonction recursive
    Par eclipse012 dans le forum PHP & Base de données
    Réponses: 9
    Dernier message: 06/11/2006, 15h13
  4. [C#] probleme avec une fonction recursive
    Par K_!!! dans le forum ASP.NET
    Réponses: 2
    Dernier message: 01/08/2006, 18h22
  5. [Debutante] Fonction recursive avec un pointeur
    Par kidney dans le forum Débuter
    Réponses: 9
    Dernier message: 25/03/2006, 08h08

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