Announcement

Collapse
No announcement yet.

Problem mit SQL Abfrage Sum()

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Problem mit SQL Abfrage Sum()

    Hi Leute,
    hab mal wieder ein Problem mit meinem Progrmm und der MS Access DB.

    Verbindung Abfragen usw. steht und funktioniert auch alles.
    Hab eine Tabelle mitarbeiter mit dem Feld: betrag
    betrag ist vom Typ float.
    Nun mach ich eine Abfrage:

    SELECT sum(betrag) FROM mitarbeiter

    Das Beste ist, WENN kein Mitarbeiter einen KommaBetrag hat sprich 1,25 oder so ..also wenn alle GanzzahlWerte haben 1€ oder 2€ usw. funktioniert die Abfrage OHNE Probleme. Hat ein mitarbeiter einen KommaBetrag kommt immer die Fehlermeldung: Daten abgeschnitten.

    Kann mir da vielleicht Jemand weiterhelfen? Typ mit dem ich drauf zugrief eist bei der Uebergabe Single und ich kann auch sonst Betrag ein,auslesen damit rechnen alles gar kein Thema nur sum() stellt sich mit Kommastellen an.

    Hab schon überlegt ob ich einfach alle Mitarbeiter selektiere und von Hand summiere aber das wäre mein absolut letzter Notnagel.

  • #2
    Mal abgesehen, das es bei Access kein Float gibt, sondern nur Single, Double und Dezimal:
    Mit dem Summieren von Nachkommazahlen hatte ich noch nie ein Problem, das geht einwandfrei.

    Die Meldung kenne ich eigentlich nur, wenn man versucht, in ein Text-Feld einen längeren String einzufügen, als es per Defintion zulässt; dann wird der Rest abgeschnitten.

    Was ist "Dein Programm", wie wird auf die MDB zugegriffen, etc (also bitte mehr Infos)?

    Wenn es eine Eigenentwicklung ist, dann lass Dir mal den Datentypen ausgeben (falls man soweit kommt).
    Olaf Helper

    <Blog> <Xing>
    * cogito ergo sum * errare humanum est * quote erat demonstrandum *
    Wenn ich denke, ist das ein Fehler und das beweise ich täglich

    Comment


    • #3
      Erst einmal Danke dafür, daß Du überhaupt geantwortet hast.

      Ich greife über ODBC auf eine Access Datenbank zu.
      Sorry in der Access DB ist der Typ Single -nur in meinem Programm beim rechnen usw. benutze ich einen Float.

      Hab hier mal den Code meiner Klasse:

      --------------------------------------------------------------
      Mitarbeiter.h
      --------------------------------------------------------------

      // -------------------------------------------------------
      //
      // MITARBEITER
      //
      // -------------------------------------------------------
      class Data_Mitarbeiter : public CRecordset
      {
      public:
      Data_Mitarbeiter(CDatabase* pDatabase = NULL);
      DECLARE_DYNAMIC(Data_Mitarbeiter)

      // Feld-/Parameterdaten
      //{{AFX_FIELD(Data_Mitarbeiter, CRecordset)
      long m_id;
      CString m_name;
      CString m_vorname;
      CString m_transponder;
      float m_betrag;
      //}}AFX_FIELD


      // Überschreibungen
      // Vom Klassen-Assistenten generierte virtuelle Funktionsüberschreibungen
      //{{AFX_VIRTUAL(Data_Mitarbeiter)
      public:
      virtual CString GetDefaultConnect(); // Standard-Verbindungszeichenfolge
      virtual CString GetDefaultSQL(); // Standard-SQL für Satzgruppe
      virtual void DoFieldExchange(CFieldExchange* pFX); // RFX-Unterstützung
      //}}AFX_VIRTUAL
      };

      --------------------------------------------------------------
      Mitarbeiter.cpp
      --------------------------------------------------------------

      IMPLEMENT_DYNAMIC(Data_Mitarbeiter, CRecordset)

      Data_Mitarbeiter:ata_Mitarbeiter(CDatabase* pdb)
      : CRecordset(pdb)
      {
      //{{AFX_FIELD_INIT(Data_Mitarbeiter)
      m_id = 0;
      m_name = "";
      m_vorname = "";
      m_transponder = "";
      m_betrag = 0.00;
      m_nFields = 5;
      //}}AFX_FIELD_INIT
      m_nDefaultType = dynaset;
      }

      CString Data_Mitarbeiter::GetDefaultConnect()
      {
      return _T("ODBC;DSN=Microsoft Access-Datenbank");
      }

      CString Data_Mitarbeiter::GetDefaultSQL()
      {
      return _T("[Mitarbeiter]");
      }

      void Data_Mitarbeiter:oFieldExchange(CFieldExchange* pFX)
      {
      //{{AFX_FIELD_MAP(Data_Mitarbeiter)
      pFX->SetFieldType(CFieldExchange:utputColumn);
      RFX_Long(pFX, _T("[id]"), m_id);
      RFX_Text(pFX, _T("[name]"), m_name);
      RFX_Text(pFX, _T("[vorname]"), m_vorname);
      RFX_Text(pFX, _T("[transponder]"), m_transponder);
      RFX_Single(pFX, _T("[betrag]"), m_betrag);
      //}}AFX_FIELD_MAP
      }


      Ich öffne dann den Dataset mit dieser Funktion:

      // ----------------------------------------------------------------------------
      // OPEN DATASET MITARBEITER
      // ----------------------------------------------------------------------------
      // Rueckgabewerte: 0 - Alles ok
      // -3 - Datenbestand erlaubt kein Anfuegen von Daten
      // -4 - Keine Datensaetze vorhanden, kann deswegen nichts anfuegen
      int CDatabaseAccess:penDatasetMitarbeiter(CString sqlBefehl="Select * FROM [Mitarbeiter]", int iModus=1)
      {
      int iRueckgabeCode = 0;

      switch(iModus)
      {
      case 1: // NUR LESEND OEFFNEN
      {
      // Datenbestand oeffnen
      this->datenbestandMitarbeiter->Open(CRecordset::snapshot, _T( sqlBefehl ), CRecordset::readOnly);
      break;
      }
      case 2: // AENDERN ERMOEGLICHEN OEFFNEN
      {
      // Datenbestand oeffnen
      this->datenbestandMitarbeiter->Open(CRecordset::dynaset, _T( sqlBefehl ), CRecordset::none);

      // Pruefen ob der Datenbestand es erlaubt neue Datensaetze anzufuegen
      if( !this->datenbestandMitarbeiter->CanAppend( ) )
      {
      // Datenbestand erlaubt kein hinzufuegen neuer Daten
      iRueckgabeCode = -3;
      return iRueckgabeCode;
      }
      if(this->datenbestandMitarbeiter->GetRecordCount() < 1)
      {
      // Weniger als ein Datensatz vorhanden - kann deswegen keinen Datensatz 'anhaengen'
      iRueckgabeCode = -4;
      return iRueckgabeCode;
      }

      break;
      }
      }

      return iRueckgabeCode;
      }

      Mit folgendem Aufruf:

      sqlBefehl = "SELECT sum( betrag ) FROM [Mitarbeiter]";
      openDatasetMitarbeiter(sqlBefehl);

      Wie gesagt wenn die Beträge keinen KommarBetrag enthalten funzt dies auch ohne Probleme.

      So hab jetzt nochmal in die DB geguckt hier nochmal die Definition aus der DB wie das Feld festgelegt ist:

      betrag
      Format: Euro
      Dezimalstellenanzeige: 2
      Standardwert: 0

      Felddatentyp: Währung

      Diese Infos hab ich aus der EntwurfAnsicht.

      Comment


      • #4
        Iiiih, C++ ... das kann ich als Normalsterblicher nicht lesen. :-)

        Die Stelle, wo Du "SELECT Sum(Betrag)..." abrufst, finde ich auch nicht

        Felddatentyp: Währung
        Also doch nicht vom Typ Zahl=>Single oder Double

        In VB (hehe, das ist meine bevorzugte ...) gibt es den Datentyp Currency als Pendant.

        Wenn ich mich recht entsinne, hatten wir auch schon Problem damit, Currency-Werte an C++ (und C#) zu übergeben und haben es deshalb auf Double abgeändert.
        Ging zwar um 'ne DLL, aber ein Versuch ist es Wert: Stell mal in der MDB den Typ auf Zahl=>Double um.
        Olaf Helper

        <Blog> <Xing>
        * cogito ergo sum * errare humanum est * quote erat demonstrandum *
        Wenn ich denke, ist das ein Fehler und das beweise ich täglich

        Comment


        • #5
          Hallo,

          ich würde die Abfrage einmal in der ACCESS-Umgebung direkt eingeben und schauen was da herauskommt.

          Gruß
          docendo discimus

          Comment


          • #6
            Oder in die MDB eine Abfrage (View) einbauen und es mit der mal probieren.
            Olaf Helper

            <Blog> <Xing>
            * cogito ergo sum * errare humanum est * quote erat demonstrandum *
            Wenn ich denke, ist das ein Fehler und das beweise ich täglich

            Comment


            • #7
              Originally posted by O. Helper View Post
              Die Stelle, wo Du "SELECT Sum(Betrag)..." abrufst, finde ich auch nicht
              Wieso? Der Aufruf, wie beschrieben:

              sqlBefehl = "SELECT sum( betrag ) FROM [Mitarbeiter]";
              openDatasetMitarbeiter(sqlBefehl);

              und oben ist die Funktion openDatasetMitarbeiter ..der die Uebergabe sqlBefehl hat und dann unter

              Datenbestand oeffnen steht es doch... da wird sqlBefehl benutzt...
              this->datenbestandMitarbeiter->Open(CRecordset::snapshot, _T( sqlBefehl ), CRecordset::readOnly);

              und auf das öffnen des Datasets bekomme ich auch die Exception "Daten abgeschnitten".

              Originally posted by O. Helper View Post
              Also doch nicht vom Typ Zahl=>Single oder Double

              In VB (hehe, das ist meine bevorzugte ...) gibt es den Datentyp Currency als Pendant.

              Wenn ich mich recht entsinne, hatten wir auch schon Problem damit, Currency-Werte an C++ (und C#) zu übergeben und haben es deshalb auf Double abgeändert.
              Ging zwar um 'ne DLL, aber ein Versuch ist es Wert: Stell mal in der MDB den Typ auf Zahl=>Double um.
              Also in der DB hab ich den Typ jetzt hin und her geändert, da tut sich nichts. LEIDER! Werde jetzt aber mal sehen ob ich statt Single auch irgendwie was finde was dem Währung in VB entspricht.
              Erstmal danke....boah dieses S******Problem

              Comment


              • #8
                Originally posted by O. Helper View Post
                Oder in die MDB eine Abfrage (View) einbauen und es mit der mal probieren.
                Meine Abfrage die ich unter Access eingegeben habe:

                SELECT sum([betrag])
                FROM Mitarbeiter;

                funktioniert OHNE Probleme. Also ich hab die Abfrage jetzt in Access und dort wirft er mir nun das richtig Ergebnis aus. Du meinst ich soll auf das Ergebnis AUS meinem Programm zugreifen???
                Zuletzt editiert von HottiDeluxe; 11.07.2008, 11:01.

                Comment


                • #9
                  Du meinst ich soll auf das Ergebnis AUS meinem Programm zugreifen???
                  Ja, falls es geht und nicht der gleiche Fehler kommt; muss man fast mit rechnen.

                  Wird nur unpraktisch, wenn Parameter fürs Filtern benötigt werden.
                  Olaf Helper

                  <Blog> <Xing>
                  * cogito ergo sum * errare humanum est * quote erat demonstrandum *
                  Wenn ich denke, ist das ein Fehler und das beweise ich täglich

                  Comment


                  • #10
                    Originally posted by O. Helper View Post
                    Ja, falls es geht und nicht der gleiche Fehler kommt; muss man fast mit rechnen.

                    Wird nur unpraktisch, wenn Parameter fürs Filtern benötigt werden.
                    So ich greife nun direkt auf die Abfrage zu.

                    sqlBefehl = "SELECT * FROM [Abfrage1]";

                    Abfrage1 wirft mir die Summe in Access richtig raus etc. UND WAS SOLL ICH SAGEN....

                    Es passiert exakt das GLEICHE! Daten abgeschnitten....ich HASSE diese Exception! Sobald die Summe 60€ anstatt 60,50€ ergiebt funzt es wieder.......

                    Comment


                    • #11
                      Nächster Versuch ... damit keine Langeweile aufkommt.

                      Versuch mal bereist im SQL eine Typkonvertierung; entweder im View oder in Deinem Code (CDbl konvertiert in Double)

                      SELECT cdbl(Sum(Betrag)) AS SummevonBetrag
                      FROM Mitarbeiter;

                      Oder gleich in String mit CStr:

                      SELECT cstr(Sum(Betrag)) AS SummevonBetrag
                      FROM Mitarbeiter;


                      Das wäre dann aber auch schon meine letzte Idee; sorry.
                      Olaf Helper

                      <Blog> <Xing>
                      * cogito ergo sum * errare humanum est * quote erat demonstrandum *
                      Wenn ich denke, ist das ein Fehler und das beweise ich täglich

                      Comment


                      • #12
                        Hi,

                        kann an Punkt und Komma liegen. Wahrscheinlich liefert Dir ACCESS den Wert mit Komma und in Deinem Programm wird ein Punkt gebraucht.

                        Gruß
                        docendo discimus

                        Comment


                        • #13
                          Originally posted by O. Helper View Post
                          Nächster Versuch ... damit keine Langeweile aufkommt.

                          Versuch mal bereist im SQL eine Typkonvertierung; entweder im View oder in Deinem Code (CDbl konvertiert in Double)

                          SELECT cdbl(Sum(Betrag)) AS SummevonBetrag
                          FROM Mitarbeiter;

                          Oder gleich in String mit CStr:

                          SELECT cstr(Sum(Betrag)) AS SummevonBetrag
                          FROM Mitarbeiter;


                          Das wäre dann aber auch schon meine letzte Idee; sorry.

                          Beides auch gescheitert...LEIDER

                          Dann bekomme ich allerdings:
                          Error: fetching row from server.
                          Fehler in Zeile
                          Ungültiger Zeichenwert für Konvertierungsangabe. bei Spalte 1
                          (Summe)

                          State:01S01,Native:9,Origin:[Microsoft][ODBC Microsoft Access Driver]
                          State:2200
                          5,Native:39,Origin:[Microsoft][ODBC Microsoft Access Driver]

                          Fehler beim Abruf eines Datensatzes.
                          Nicht abgefangene Ausnahme in Kantine.exe (KERNEL32.DLL): 0xE06D7363: Microsoft C++ Exception.
                          Nicht abgefangene Ausnahme in Kantine.exe (KERNEL32.DLL): 0xE06D7363: Microsoft C++ Exception.

                          Comment


                          • #14
                            Originally posted by frauwue View Post
                            Hi,

                            kann an Punkt und Komma liegen. Wahrscheinlich liefert Dir ACCESS den Wert mit Komma und in Deinem Programm wird ein Punkt gebraucht.

                            Gruß
                            Da das Ganze ja funktioniert, wenn eine GANZzahl rauskommt sprich 60€ oder 50€ und nur aufschlagen geht wenn zum Beispiel beim Summieren eine KommaZahl rauskommt 50,75€ etc. gehe ich auch stark davon aus.

                            BLOS wie umgehe ich das bzw. konvertiere ich das vorher richtig um etc.? Er geht ja bereits beim öffnen des Datasets aufschlagen sprich bei der Uebergabe des Ergebnisses des SQLs....die Idee von O.Helper war deswegen gar nicht so schlecht, daß ganze vorher schon zu konvertieren, dass klappt aber auch nicht wirklich....gleiche Fehlermeldung....selbst wenn ich in Access da einen Zahlwert draus mache.....hab aber echt keine Lust einen BETRAG in Access als Text zu speichern....(was eine Summierung dann wahrscheinlich eh unmöglich machen würde)

                            Comment


                            • #15
                              Hi,

                              kannst Du den Wert von Deinem Programm aus nicht direkt als String anstatt als Float einlesen ohne Konvertierung dazwischen?


                              Gruß
                              docendo discimus

                              Comment

                              Working...
                              X