Menu

Calcul de la somme d'une colonne

Streamooc 55 Messages postés samedi 17 juin 2017Date d'inscription 10 septembre 2018 Dernière intervention - 1 août 2018 à 22:38 - Dernière réponse : KX 15723 Messages postés samedi 31 mai 2008Date d'inscriptionModérateurStatut 18 septembre 2018 Dernière intervention
- 10 sept. 2018 à 23:31
Bonjour à tous.Je désire calculer la somme des factures de la journée.Ce que j'ai écris n'est pas correcte.Comment je fais le type de retour ? La requête également ? J'ai besoin qu'on m'aide à le corriger s'il vous plaît.

@Override
 public double totalJour(Facture facture) {
  
   facture=null;
  try {
   //Préparation de la requête
   String sql="SELECT SUM (factures_montants) AS facturetotale FROM factures WHERE factures_date_limite like ?";
    //Création d'une zone de requête
   PreparedStatement pst=conn.prepareStatement(sql);
   
   //Exécution de la requête
   ResultSet rs=pst.executeQuery();
   //Traitement du résultat de la requête
   while (rs.next()) {
    int id = Integer.parseInt(rs.getString("idfactures"));
    String numerofact = rs.getString("factures_numero");
    String montant = rs.getString("factures_montants");
    Date datelim = rs.getDate("factures_date_limite");
    int idPays = rs.getInt("facturiers_idfacturiers");
    facture=new Facture(id, numerofact, montant,datelim,idPays);
    
   }
  } catch (NumberFormatException e) {
   e.printStackTrace();
  } catch (SQLException e) {
   System.out.println("Problème de requête");
   e.printStackTrace();
  }
  return ;
 }
public class Facture implements Serializable {
 private int idfactures;
 private String factures_numero;
 private String factures_montants;
 private Date factures_date_limite;
 private int facturiers_idfacturiers;
}

CREATE TABLE `factures` (
  `idfactures` int(11) NOT NULL,
  `factures_numero` varchar(45) NOT NULL,
  `factures_montants` varchar(45) DEFAULT NULL,
  `factures_date_limite` date DEFAULT NULL,
  `facturiers_idfacturiers` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;


EDIT : Ajout des balises de code (la coloration syntaxique).
Explications disponibles ici : ICI

Merci d'y penser dans tes prochains messages.
Afficher la suite 

Votre réponse

23 réponses

KX 15723 Messages postés samedi 31 mai 2008Date d'inscriptionModérateurStatut 18 septembre 2018 Dernière intervention - 1 août 2018 à 23:44
0
Merci
Bonjour,

Le problème c'est que tu as masqué l'exception, elle s'affiche dans les logs donc il faudrait la lire, mais sans surprise tu auras une SQLException car tu as fait une requête avec un
?
sans faire de
set
donc ton paramètre n'a aucune valeur et ta requête est fausse, elle ne peut donc pas renvoyer de résultat.
KX 15723 Messages postés samedi 31 mai 2008Date d'inscriptionModérateurStatut 18 septembre 2018 Dernière intervention > Streamooc 55 Messages postés samedi 17 juin 2017Date d'inscription 10 septembre 2018 Dernière intervention - 6 août 2018 à 17:07
Le mieux c'est serait de te relire toi même. Là ça relève de l'étourderie, l'erreur de copier-coller...

String date1=request.getParameter("factures_date_limite");
String date2=request.getParameter("factures_date_limite");

Tu appelles deux fois la même méthode avec le même paramètre, donc le résultat sera forcément le même.
Avec ce code, tu auras forcément date1 et date2 identiques...

Mais le vrai problème est dans ta vue :

<input id="chercherL"
           class="footer__email-input form-control form-control--muted"
           name="factures_date_limite" type="text" aria-describedby="footerEmail" 
           placeholder="date 1" >
<input id="chercherL"
           class="footer__email-input form-control form-control--muted"
           name="factures_date_limite" type="text" aria-describedby="footerEmail" 
           placeholder="date 2" > 

Tout est identique... il faut distinguer la date de début et la date de fin.
Streamooc 55 Messages postés samedi 17 juin 2017Date d'inscription 10 septembre 2018 Dernière intervention - 14 août 2018 à 03:57
Merci beaucoup KX j'ai suivi ces conseils et ça m'a aidé à résoudre ce problème.L'autre souci que j'ai c'est que je dois afficher un message d'erreur au cas où l'état de compte saisi n'existe pas.Dans le cas contraire je dois afficher la liste des comptes.Avec ce code lorsque l'état saisi n'existe pas il affiche bien le message d'erreur mais lorsque l'état saisi existe il affiche juste "état de compte" qui se trouve au niveau du traitement,il ne me charge pas les données attendues.J'ai besoin encore de votre aide s'il vous plaît
//Controleur
protected void doPost(HttpServletRequest request, HttpServletResponse response)
   throws ServletException, IOException {
  
  String etaSaisi=request.getParameter("motCle");
  String action = request.getParameter("action");
  
  Client client=new Client();
  client.setClients_etat_compte(etaSaisi);
  
  ServiceClientImpl serv=new ServiceClientImpl();
    String etatValide=serv.verifierSituation(client);

    ClientModel model=new ClientModel();
  
    request.setAttribute("model", model);
   
    if (action != null) { 
     if (action.equals("Rechercher")) {
      if (etaSaisi.equals(etatValide)) {
       
       model.setMotCle(request.getParameter("motCle"));
        List<Client> clients=serv.researchCustomerByCountState(model.getMotCle());
       
       model.setClients(clients);
      request.getRequestDispatcher("client/rapportEtatCompte.jsp").forward(request, response);

      } else {
       request.setAttribute("erreurMessage", etatValide);
       request.getRequestDispatcher("client/errorCompte.jsp").forward(request, response);
       
      }
     
     }
    }
 }

////////////Traitement
public String verifierSituation(Client t) {
  String etatCompte=t.getClients_etat_compte();
  String etatDB="";
  
  try {
   String sql="SELECT clients_etat_compte FROM clients";
   Statement st=conn.createStatement();
   ResultSet rs=st.executeQuery(sql);
   while(rs.next()) {
    etatDB=rs.getString("clients_etat_compte");
    if (etatCompte.equals(etatDB)){
     return "état de compte";
    }     
   }
   
  } catch (SQLException e) {
   e.printStackTrace();
  }
  return "Cet état de compte n'existe pas !!!!";
 }
KX 15723 Messages postés samedi 31 mai 2008Date d'inscriptionModérateurStatut 18 septembre 2018 Dernière intervention > Streamooc 55 Messages postés samedi 17 juin 2017Date d'inscription 10 septembre 2018 Dernière intervention - 14 août 2018 à 22:21
"il ne me charge pas les données attendues"
Et quelles sont les données attendues ?
Si c'est juste une vérification le résultat que tu dois avoir c'est vrai ou faux.

Remarque : faire un SELECT qui récupère toutes les lignes de la table pour ensuite faire une boucle while qui va vérifier un à un si la valeur est égal à un paramètre, c'est monstrueusement inefficace !
Il faut que tu retravailles ta requêtes SQL avec un WHERE qui regardera directement la bonne ligne dans la base de données et remontera un seul résultat (s'il existe) ou aucun.
Streamooc 55 Messages postés samedi 17 juin 2017Date d'inscription 10 septembre 2018 Dernière intervention - 28 août 2018 à 04:47
Merci beaucoup KX j'ai finalement trouvé le moyen de le faire.Cette fois-ci le problème que j'ai c'est comment afficher un message d'erreur à l'utilisateur lorsqu'il clique sur le bouton "Rechercher" sans saisir une valeur dans le champ de recherche.Je ne sais pas comment procéder.J'ai besoin de votre aide s'il vous plaît.

//Vue
                                                                   <div class="form-group w-100 mr-2">
          <input id="chercherL"
           class="footer__email-input form-control form-control--muted"
           name="motCle" type="text" aria-describedby="footerEmail" 
           placeholder="Recherchez " value="${model.motCle }">
                                                        </div>



//Contrôleur
             String champSaisie=request.getParameter("motCle");
      String action = request.getParameter("action");
  
               request.setAttribute("champSaisie", champSaisie);
  if (action != null) { 
   if (action.equals("Rechercher")) {
    
      if (champSaisie !=null) {
     
        request.getRequestDispatcher("solde/rapportSolde.jsp").forward(request, response);

   } else {
    request.getRequestDispatcher("solde/error.jsp").forward(request, response);

   } 
   }
  }
Streamooc 55 Messages postés samedi 17 juin 2017Date d'inscription 10 septembre 2018 Dernière intervention - 29 août 2018 à 10:36
Bonjour KX.J'ai finalement corrigé ce problème avec les exemples précédents.Merci beaucoup pour votre aide.Toutefois j'ai quelques soucis toujours avec les calculs sur plusieurs colonnes dont je vous ferai part bientôt.
Commenter la réponse de KX
Streamooc 55 Messages postés samedi 17 juin 2017Date d'inscription 10 septembre 2018 Dernière intervention - 5 sept. 2018 à 08:12
0
Merci
Bonjour KX.Ma base de données comprend des enregistrements au format année-mois-jour heure-minute-seconde par exemple 2018-08-02 11:59:51.0.Je voudrais calculer la somme seulement entre des intervalles de mois.Lorsque l'utilisateur saisit par exemple 2017-02 et 2019-08 la somme entre ces deux intervalles devra être affichée.Ma requête ne passe pas.Veuillez me la regarder s'il vous plaît:
public double totalIntervalleMois(String mi, String mf) {
String sql = "SELECT SUM(montant) FROM operations WHERE date BETWEEN ? AND ?";
try (PreparedStatement pst = conn.prepareStatement(sql)) {
pst.setString(1,mi);
pst.setString(2,mf);
try (ResultSet rs = pst.executeQuery()) {
if (!rs.next()) {
throw new IllegalStateException("Query returns no result: " + sql);
}
double sum = rs.getDouble(1);
if (rs.wasNull()) {
throw new IllegalStateException("Query returns NULL: " + sql);
}
return sum;
}
}
catch (Exception e) {
throw new IllegalStateException("totalJour fails: " + mi + " " + mf, e);
}
}
KX 15723 Messages postés samedi 31 mai 2008Date d'inscriptionModérateurStatut 18 septembre 2018 Dernière intervention - 5 sept. 2018 à 18:04
Si la requête ne passe pas, j'imagine qu'il y a une exception, laquelle ?

Mais bon je pense que le problème c'est qu'il te faut des type DATETIME dans ta base de données, manipuler des pst.setTimestamp avec ton code Java, et donc convertir tes String au préalable...
Commenter la réponse de Streamooc
Streamooc 55 Messages postés samedi 17 juin 2017Date d'inscription 10 septembre 2018 Dernière intervention - 6 sept. 2018 à 15:43
0
Merci
Bonjour KX.
Au fait si j'utilise Timestamp celà suppose que je veux entrer des données sous le format yyyy-mm-ss hh-mm-ss.J'ai déjà géré ça dans d'autres cas et ça a marché.
Ce que je veux faire ici:l'utilisateur entre les deux dates sous ce format yyyy-mm et on lui affiche la liste de toutes les opérations correspondantes entre les deux dates par exemple 2017-02 et 2018-09.
Bien sûr que le champ 'date' dans ma base de données est au format Timestamp: yyyy-mm-ss hh-mm-ss.Voici l'erreur KX et je la trouve normale puisque c'est les deux dates sont saisies dans ce format yyyy-mm:
GRAVE: "Servlet.service()" pour la servlet sn.mobilebanking.presentation.RechercherOperationDepotMontantEntrantIntervalleMoisControlleur a généré une exception
java.lang.IllegalArgumentException: Timestamp format must be yyyy-mm-dd hh:mm:ss[.fffffffff]
at java.sql.Timestamp.valueOf(Unknown Source)
at presentation.OperationIntervalleMoisControlleur.doPost(OperationIntervalleMoisControlleur.java:47)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:650)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:731)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:219)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:110)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:169)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:962)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:445)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1115)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:637)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:318)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Unknown Source)




////////////////////////////
C'est de ces deux lignes d'où survient l'erreur:
Timestamp date1=Timestamp.valueOf(request.getParameter("date_debut"));
Timestamp date2=Timestamp.valueOf(request.getParameter("date_fin"));
////////
<label>Saisissez les deux mois</label>
<input id=""
class="footer__email-input form-control form-control--muted"
name="date_debut" type="text" aria-describedby="footerEmail"
placeholder="Année-Mois1" >

<input id=""
class="footer__email-input form-control form-control--muted"
name="date_fin" type="text" aria-describedby="footerEmail"
placeholder="Année-Mois2" >






//////
public double totalIntervalleMois(Timestamp mois1, Timestamp mois2) {
String sql = "SELECT SUM(montant) FROM operations WHERE date BETWEEN ? AND ?";
try (PreparedStatement pst = conn.prepareStatement(sql)) {
pst.setTimestamp(1,mois1);
pst.setTimestamp(2,mois2);
try (ResultSet rs = pst.executeQuery()) {
if (!rs.next()) {
throw new IllegalStateException("Query returns no result: " + sql);
}
double sum = rs.getDouble(1);
if (rs.wasNull()) {
throw new IllegalStateException("Query returns NULL: " + sql);
}
return sum;
}
}
catch (Exception e) {
throw new IllegalStateException("totalJour fails: " + mois1 + " " + mois2, e);
}
}
KX 15723 Messages postés samedi 31 mai 2008Date d'inscriptionModérateurStatut 18 septembre 2018 Dernière intervention - 6 sept. 2018 à 18:05
C'est ce que je disais, il faut convertir tes String au préalable.
Tu as le format
yyyy-mm-ss hh-mm-ss
il faut le convertir en
yyyy-mm-dd hh:mm:ss
pour le passer en Timestamp.
Commenter la réponse de Streamooc
Streamooc 55 Messages postés samedi 17 juin 2017Date d'inscription 10 septembre 2018 Dernière intervention - 7 sept. 2018 à 02:27
0
Merci
Bonjour KX. Bien sûr c'est ce format yyyy-mm-dd hh:mm:ss que j'ai
KX 15723 Messages postés samedi 31 mai 2008Date d'inscriptionModérateurStatut 18 septembre 2018 Dernière intervention - 7 sept. 2018 à 13:09
Affiches tes deux String request.getParameter("date_debut") et request.getParameter("date_fin") pour voir à quoi il ressemble et pourquoi le valueOf ne fonctionne pas.
Commenter la réponse de Streamooc
Streamooc 55 Messages postés samedi 17 juin 2017Date d'inscription 10 septembre 2018 Dernière intervention - Modifié par KX le 10/09/2018 à 23:23
0
Merci
Bonjour KX.L'affichage donne les données saisies:
Date de début:2017-07
Date de fin:2018-09

java.lang.IllegalStateException: totalJour fails: 2018-07 2018-09
 at sn.mobilebanking.dao.DaoOperationRetraitImpl.totalOperationRetraitParIntervalleMois(DaoOperationRetraitImpl.java:404)
 at sn.mobilebanking.service.ServiceOperationRetraitImpl.totalOperationRetraitParIntervalleMois(ServiceOperationRetraitImpl.java:68)
 at sn.mobilebanking.presentation.RechercherOperationRetraitMontantSortantIntervalleMoisControlleur.doPost(RechercherOperationRetraitMontantSortantIntervalleMoisControlleur.java:64)
 at javax.servlet.http.HttpServlet.service(HttpServlet.java:650)
 at javax.servlet.http.HttpServlet.service(HttpServlet.java:731)
 at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
 at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
 at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
 at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
 at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
 at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:219)
 at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:110)
 at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:169)
 at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
 at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:962)
 at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
 at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:445)
 at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1115)
 at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:637)
 at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:316)
 at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
 at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
 at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
 at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.IllegalStateException: Query returns NULL: SELECT SUM(montant_retrait) FROM operation_retrait WHERE operation_retraitdate like ? AND operation_retraitdate like ?
 at sn.mobilebanking.dao.DaoOperationRetraitImpl.totalOperationRetraitParIntervalleMois(DaoOperationRetraitImpl.java:398)

//Quelque soit la requête que j'utilise rien ne marche:
public double totalOperationRetraitParIntervalleMois(String moisDebut, String moisFin) {
  String sql = "SELECT SUM(montant_retrait) FROM operation_retrait WHERE operation_retraitdate like ? AND operation_retraitdate like ?";
     try (PreparedStatement pst = conn.prepareStatement(sql)) {
         pst.setString(1,moisDebut);
         pst.setString(2,moisFin);
   
         try (ResultSet rs = pst.executeQuery()) {
             if (!rs.next()) {
                 throw new IllegalStateException("Query returns no result: " + sql);
             }
             double sum = rs.getDouble(1);
             if (rs.wasNull()) {
                 throw new IllegalStateException("Query returns NULL: " + sql);
             }
             return sum;
         }
     }
     catch (Exception e) {
         throw new IllegalStateException("totalJour fails: "  + moisDebut + " " + moisFin, e);
     }
 }

//doPost
 double total=0;
  
  String date1=request.getParameter("date_debut");
  String date2=request.getParameter("date_fin");
  String action=request.getParameter("action");

 total=serv.totalOperationRetraitParIntervalleMois(date1, date2);


//Vue
  <label>Saisissez les deux mois</label>
                                     <input id=""
           class="footer__email-input form-control form-control--muted"
           name="date_debut" type="text" aria-describedby="footerEmail" 
           placeholder="Année-Mois1" >
     
           <input id=""
           class="footer__email-input form-control form-control--muted"
           name="date_fin" type="text" aria-describedby="footerEmail" 
           placeholder="Année-Mois2" >
KX 15723 Messages postés samedi 31 mai 2008Date d'inscriptionModérateurStatut 18 septembre 2018 Dernière intervention - 10 sept. 2018 à 23:31
En SQL si tu fais un
like
il faut rajouter un wildcard, par exemple
like '2018-07-%'
mais si tu fais
like '2018-07'
ça ne trouvera jamais aucun résultat, or le
SUM
de rien c'est
NULL
, d'où ton erreur "Query returns NULL"

Mais l'erreur c'est encore et toujours ton format de dates, il faut davantage utiliser les types DATE, TIME, DATETIME ou TIMESTAMP du langage, car tout ne se règle pas avec des VARCHAR...
Commenter la réponse de Streamooc