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 :

Exécuter une requête avec des parametres récupérés dans des Object[]


Sujet :

JDBC Java

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    29
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 29
    Points : 21
    Points
    21
    Par défaut Exécuter une requête avec des parametres récupérés dans des Object[]
    Bonjour à tous,

    J'ai 3 composants JList (mois, clients) dans lesquels il est possible de sélectionner un ou plusieurs éléments.

    Les éléments sélectionnés sont respectivement placés dans des tableaux d'objets qui portent les mêmes noms.

    Ce que je voudrais faire, c'est effectuer une requête paramétrée pour tous les mois sélectionnés, tous les clients sélectionnés et tous les articles sélectionnés.

    Je m'y prends de cette façon :

    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
     
    private Object[] mois;
    private Object[] clients;
    Vector tabLignes = new Vector();
    StringBuffer sb = new StringBuffer(20);
     
    	String requete = "SELECT distinct MONTHNAME( dateExpReelle ) AS Mois, Clients, Articles, COUNT(Articles) AS 'Nombre 						articles en retard', SUM(prix) as 'Valeur des articles en retard (en €)' " +
    	"FROM articles, commande, clients " +
    	"WHERE articles.codeArticle = commande.codeArticle AND clients.codeClient = commande.codeClient " +
    	"AND Clients = ? " +
    	"AND dateExpReelle > dateExpPrevue " +
    	"AND MONTHNAME(dateExpReelle)= ? " +
    	"GROUP BY Articles;";
     
    	PreparedStatement stmt = connexion.prepareStatement(requete);
    	if(clients!=null){
    		for(int n=0;n<clients.length;n++){
    			stmt.setString(1, clients[n].toString());
    		}
    	}else {
    		System.out.println("Aucune donnée ne correspond à votre demande.");
    	}
     
    	if(mois!=null){
    		for(int j=0;j<mois.length;j++){
    			sb.append(mois[j]+" ");
    			stmt.setString(2, mois[j].toString());
    		}
    	}else {
    		System.out.println("Aucune donnée ne correspond à votre demande.");
    	}
     
     
    	rs = stmt.executeQuery();
     
    	// Mémoriser le résultat dans la JTable
    	while( rs.next()) {
     
    		//le 5 designe le nombre de colonnes qui seront récupérées suite à la requête
    		for(int i=1; i<=5; i++) 
    		{
    			String ch = rs.getString(i);
    			ligne.add(ch); //placer les valeurs dans Vector ligne
    		}
    		tabLignes.add(ligne);
    	}
    }
    Quand j'exécute ce code, aucune donnée ne m'est retournée alors qu'il existe bien des enregistrements pour les tests que je fais.

    Pourriez vous m'aider ?

  2. #2
    Membre actif Avatar de aperrin
    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    221
    Détails du profil
    Informations personnelles :
    Âge : 51
    Localisation : France

    Informations forums :
    Inscription : Octobre 2005
    Messages : 221
    Points : 272
    Points
    272
    Par défaut
    Le statement ne marche que pour un paramètre cela ne sert à rien de faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    for(int j=0;j<mois.length;j++){
    			sb.append(mois[j]+" ");
    			stmt.setString(2, mois[j].toString());
    		}
    Il faut une fonction (et une requête) pour un client et un mois et itérer autant de fois que de paramètres sélectionnés.
    Ou utiliser la clause in et construire directement une requête à la main.
    En essayant continuellement, on finit par réussir. Donc plus ça rate, plus on a de chances que ça marche !

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

    Informations forums :
    Inscription : Novembre 2006
    Messages : 7 310
    Points : 9 522
    Points
    9 522
    Billets dans le blog
    1
    Par défaut
    Il serait plus simple (dans ce cas) de passer par un Statement et de générer des clauses "in" pour tes listes
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    SELECT distinct 
        MONTHNAME( dateExpReelle ) AS Mois, 
        Clients, 
        Articles, 
        COUNT(Articles) AS 'Nombre articles en retard', 
        SUM(prix) as 'Valeur des articles en retard (en €)' 
    FROM articles, commande, clients
    WHERE articles.codeArticle = commande.codeArticle AND clients.codeClient = commande.codeClient
    AND Clients in (...)
    AND Articles in (...)
    AND MONTHNAME(dateExpReelle) in (...)
    etc...
    Par concaténation des valeurs des tes listes, tu créés la requête qui va bien.

    Si tu dois absolument passer par un PreparedStatement, tu peux le faire également, mais en 2 fois.
    Tu génères la chaîne de requête qui contiendra les "in (?, ?, ?, ..., ?)"
    Tu créés ton preparedStatement
    Tu affectes les valeurs des paramètres en utilisant les listes de valeurs dans l'ordre où elles ont été utilisées pour créer la chaîne de requête.

    Avec Hibernate, tu aurais pu mettre un liste comme paramètre, mais comme tu utilises du JDBC standard, on ne peut pas (dommage)
    (C'est juste à titre d'information )

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

  4. #4
    Membre à l'essai
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    29
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 29
    Points : 21
    Points
    21
    Par défaut
    Merci à tous les deux pour vos réponses.

    OButterlin j'ai suivi ta piste. Je ne suis pas du tout obligée d'utiliser un PreparedStatement je pensais que ça serait plus pratique mais pas forcément finalement.

    J'ai cependant un petit soucis au niveau de la concaténation. Si je veux utiliser mes valeurs dans la clause IN de ma requête SQL, il faut que ces valeurs soient séparées par des virgules.

    J'ai fait comme ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
     
    StringBuffer sbMois = new StringBuffer(200); // 200 est une estimation de la taille maximale de la chaîne.
    for(int i =0;i<mois.length;i++)
    {
    	sbMois.append("'"+mois[i]+",");				
    }
    Mais le problème c'est que y'a une virgule après la dernière valeur et ça génère une erreur au niveau de la requête sql.

  5. #5
    Membre à l'essai
    Profil pro
    Inscrit en
    Août 2008
    Messages
    24
    Détails du profil
    Informations personnelles :
    Âge : 54
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 24
    Points : 19
    Points
    19
    Par défaut
    Effectivement avec la boucle for tu ne pourra pas faire le dernier cas, tu doit faire le dernier passage en dehors.

    Janosor

  6. #6
    Membre à l'essai
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    29
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 29
    Points : 21
    Points
    21
    Par défaut
    Effectivement j'ai modifié mon code. J'ai mis en fait le premier élément hors de la boucle mais j'ai un nouveau problème.

    Lorsque j'exécute ma requête, elle ne me renvoit jamais le 1er résultat présent dans mon resultSet, je n'ai toujours que ceux qui suivent.

    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
    51
    52
    53
    54
    55
    56
    57
    58
     
    // Récupération des mois
    StringBuffer sbMois = new StringBuffer(200); // 200 est une estimation de la taille maximale de la chaîne.
    	if (mois.length>0) {
    		sbMois.append("'"+mois[0]+"'");
    		for(int i=1;i<mois.length;i++){
                          sbMois.append(",").append("'"+mois[i]+"'");				
    	        }
    	}
     
    // Récupération des clients
    StringBuffer sbClients = new StringBuffer(200); // 200 est une estimation de la taille maximale de la chaîne.
    	if (clients.length>0) {
    		sbClients.append("'"+clients[0]+"'");
    		for(int i=1;i<clients.length;i++) {
    		sbClients.append(",").append("'"+clients[i]+"'");				
    		}
    	}
     
    // Récupération des articles
    StringBuffer sbArticles = new StringBuffer(200); // 200 est une estimation de la taille maximale de la chaîne.
    	if (articles.length>0) {
    		sbArticles.append("'"+articles[0]+"'");
    		for(int i=1;i<articles.length;i++) {
    			sbArticles.append(",").append("'"+articles[i]+"'");		
    		}
    	}
     
    String requete = "SELECT distinct MONTHNAME( dateExpReelle ) AS Mois, Clients, Articles, COUNT(Articles) AS 'Nombre articles en retard', SUM(prix) as 'Valeur des articles en retard (en €)' " +
    "FROM articles, commande, clients " +
    "WHERE articles.codeArticle = commande.codeArticle AND clients.codeClient = commande.codeClient " +
    "AND dateExpReelle > dateExpPrevue " +
    "AND Clients in ("+sbClients.toString()+")"+
    "AND Articles in ("+sbArticles.toString()+")"+
    "AND MONTHNAME(dateExpReelle) in ("+sbMois.toString()+")GROUP BY Articles ";
     
    rs = statement.executeQuery(requete);
     
    if(rs.next()){ // Vérification que la requête retourne bien des résultats
     
    	// Mémoriser le résultat dans la JTable
    	while( rs.next()) {
    		//placer les valeurs dans Vector ligne
    		Vector ligne=new Vector();
     
    		//le 5 designe le nombre de colonnes qui seront récupérées suite à la requête
    		for(int i=1; i<=5; i++) 
    		{
    			String ch=rs.getString(i);
    			ligne.add(ch);
    		}
    		tabLignes.add(ligne);
     
    		}else{
    	String message = "Votre requête n'a retourné aucune données. \n Veuillez modifier vos paramètres.";
    	JOptionPane.showMessageDialog(null, message);
    	}
    }

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

    Informations forums :
    Inscription : Novembre 2006
    Messages : 7 310
    Points : 9 522
    Points
    9 522
    Billets dans le blog
    1
    Par défaut
    C'est un peu normal, tu fais un if ( rs.next() ) ... <- lecture du premier
    suivit d'un while ( rs.next() ) ... <- forcément, le premier étant lu dans le if, il part au deuxième...

    A part ça, il y a une chose surprenante dans ton code, tu utilises un StringBuffer, tu fais sb.append("'" + mois[i] + "'") là où j'aurais fais sb.append("'").append(mois[i]).append("'"), dommage...
    (ce n'est pas que ta méthode ne fonctionne pas, mais ça créé des variables intermédiaires inutilement...)

    Ensuite, si déjà tu as un StringBuffer, pourquoi ne pas construire toute ta chaîne de requête avec ?

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

Discussions similaires

  1. Réponses: 1
    Dernier message: 03/02/2015, 17h48
  2. Réponses: 1
    Dernier message: 02/02/2015, 15h17
  3. Réponses: 5
    Dernier message: 10/09/2011, 00h07
  4. Réponses: 4
    Dernier message: 29/09/2010, 22h55
  5. Réponses: 6
    Dernier message: 19/10/2007, 15h02

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