Laden...

SQL Sum dezimalwerte [Problem liegt beim DB-Zugriff ohne Verwendung von SQL-Parametern]

Erstellt von 27sharpme vor 10 Jahren Letzter Beitrag vor 10 Jahren 11.310 Views
Thema geschlossen
2
27sharpme Themenstarter:in
17 Beiträge seit 2013
vor 10 Jahren
SQL Sum dezimalwerte [Problem liegt beim DB-Zugriff ohne Verwendung von SQL-Parametern]

verwendetes Datenbanksystem: <SQLITE>

Hallo ,

ich versuche gerade mit 'SUM' zu addieren , doch da ich ich bekomme nur integer Werte.

Das ist mein Code :

  private SQLiteCommand sum()
        {
            SQLiteCommand cmd = new SQLiteCommand(connection);
            cmd.CommandText = String.Format("select sum(Stunde) from Times");

            
            return cmd;
        }

Ich möchte jetzt decimalwerte zurück bekommen.

vielen dank im voraus.

T
461 Beiträge seit 2013
vor 10 Jahren

Hey,

ich möchte mich täuschen aber ist 'Stunde' nicht ein integer ? Das Ergebnis kann dann nur eins ohne Nachkomma sein.

Deine Anforderung wie du Sie beschreibst ergibt für mich keinen Sinn...
Vielleicht erläuterst du es ein wenig präziser...

Ich habe den Titel mal angepasst, so dass Suchende auch etwas damit anfangen können. EDIT: Ich sollte beim Wort "Shift" im Titel das "f" nicht vergessen... 😄

C
2.121 Beiträge seit 2010
vor 10 Jahren

Wie du die Werte ausliest zeigst du nirgends.
Wenn du schon sum() zurückgeben willst, lies doch den Wert gleich aus und gib den zurück, anstatt dem Command.

2
27sharpme Themenstarter:in
17 Beiträge seit 2013
vor 10 Jahren

Also jetzt nochmal ,

die Werte in der Datenbank werden als eine Nachkommer stelle gespeichert.
Also z.B.: 1,5 ; 2 ; 2,5 ..

Nun möchte ich dies aus so addieren und nicht als Integer - Wert.

2
27sharpme Themenstarter:in
17 Beiträge seit 2013
vor 10 Jahren

Wie du die Werte ausliest zeigst du nirgends.

Warum sollte ich die Werte zuerst auslesen ?
Ich möchte die ja nur addieren und wiedergeben.

C
2.121 Beiträge seit 2010
vor 10 Jahren

Ich meinte die Stelle an der du die Summe in eine Variable einliest. Erst hier stellst du ja fest dass es ein int ist.
Wenn die Werte in der DB als Kommazahl stehen, sollte SUM auch eine Kommazahl draus machen. Dann castest du das vielleicht nur falsch.

T
461 Beiträge seit 2013
vor 10 Jahren

Ich meinte die Stelle an der du die Summe in eine Variable einliest. Erst hier stellst du ja fest dass es ein int ist.
Wenn die Werte in der DB als Kommazahl stehen, sollte SUM auch eine Kommazahl draus machen. Dann castest du das vielleicht nur falsch.

Ich bin auch der Meinung. Kannst du mal den Code zeigen, bei dem du das Ergebnis ausliest ?

Ich habe den Titel mal angepasst, so dass Suchende auch etwas damit anfangen können. EDIT: Ich sollte beim Wort "Shift" im Titel das "f" nicht vergessen... 😄

2
27sharpme Themenstarter:in
17 Beiträge seit 2013
vor 10 Jahren

Ich wollte das ergebnis in einem Label anzeigen deswegen so :

    //Database dba = new Database();
            endstdlbl.Text = dba.Sum.ExecuteScalar().ToString();

T
2.219 Beiträge seit 2008
vor 10 Jahren

ExecuteScalar liefert dir auch ein Int zurück.
Deshalb kann es eigentlich nicht klappen.
Aber das solltest du doch schon mit etwas Debugging prüfen können.

Warum verwendest du keinen DataReader und liest den Wert direkt aus und wandelst ihn in ein double um?

T-Virus

Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.

502 Beiträge seit 2004
vor 10 Jahren

ExecuteScalar liefert dir auch ein Int zurück.
Deshalb kann es eigentlich nicht klappen.

Also soweit ich das in der Doku sehe gibt ExecuteScalar nicht int sondern object zurück - ich kenn mich bei SQLite nun nicht wirklich aus, aber bei allen anderen DB-Systemen, die ich kenne, ist das so, dass in dem zurückgegebenen object das Ergebnis der ersten Spalte aus der ersten Zeile zurückkommt. Man muss es nur noch richtig casten.

D.h. wenn Stunde ein int ist, wird auch sum(Stunde) int werden und somit int zurückkommen. Hat Stunde aber einen anderen Typ, wird auch was anderes bei ExecuteScalar zurückkommen (wenn auch wieder gecastet als object).

Bart Simpson

Praxis ist wenn alles funktioniert und keiner weiss warum.
Theorie ist wenn man alles weiss, aber nichts funktioniert.

Bei uns wird Theorie und Praxis vereint: Nichts funktioniert und keiner weiss warum...

C
2.121 Beiträge seit 2010
vor 10 Jahren

Mach doch mal nen Test.
cmd.CommandText = "select 1.5"; (wozu ist hier eigentlich ein String.Format bei dir drin?)
object o = cmd.ExecuteScalar();
und dann schau im Debugger an, was o für einen Typ hat.

3.511 Beiträge seit 2005
vor 10 Jahren

Hallo,

so schwer isses doch gar net 😃

Ein SUM aus 1,2,3 = 6 = Int64
Ein SUM aus 1,2.5,3 = 6.5 = Double

Gruß
Khalid

[Edit]: SQLite entscheidet sich beim Übertragen scheinbar für den "günstigeren" Datentyp. Aber das ist nur eine reine Vermutung von mir.
[Edit2]: Scheinbar bringt dein SUM exakt ein ganzzahligen Wert raus.

"Jedes Ding hat drei Seiten, eine positive, eine negative und eine komische." (Karl Valentin)

F
115 Beiträge seit 2012
vor 10 Jahren

Hi,

kann es sein, dass die Summe Deiner Werte sich als Int darstellen läßt, weil zufällig alle Zahlen eine "glatte Summe" ergeben?

Gruß
f_igy

2
27sharpme Themenstarter:in
17 Beiträge seit 2013
vor 10 Jahren

Also so sieht meine Tabelle aus :

   private  SQLiteCommand  creattable()
        {
            SQLiteCommand command = new SQLiteCommand(connection);
            command.CommandText = String.Format("create table if not exists {0} (" +
                "  ID integer not null primary key autoincrement," +
                "  Datum  date  ," +
                "  Stunde varchar (10,2))",

                "Times");
             return command;

Die Werte für Stunde beinhalten Werte mit Nachkommastellen , deswegen kann das Ergebnis mit einer Integer Zahl nicht stimmen.

709 Beiträge seit 2008
vor 10 Jahren

Hi,
kann man Texte überhaupt per Sum addieren oder wird da gecastet?
Funktioniert es, wenn REAL oder DECIMAL statt VARCHAR genommen wird?

Gruß
pinki

F
115 Beiträge seit 2012
vor 10 Jahren

Hm,

varchar (10,2) kenne ich auch nicht als gültigen Datentypen. Auserdem kann man 1,5 + 3,2 + 4,3 = 9 natürlich nach Int casten...

f_igy

2
27sharpme Themenstarter:in
17 Beiträge seit 2013
vor 10 Jahren

kann man Texte überhaupt per Sum addieren oder wird da gecastet?
Funktioniert es, wenn REAL oder DECIMAL statt VARCHAR genommen wird?

Wenn ich das jetzt so mache bekomme ich garkeine Nachkommastellen:

"  Stunde DECIMAL )",
2
27sharpme Themenstarter:in
17 Beiträge seit 2013
vor 10 Jahren

varchar (10,2) kenne ich auch nicht als gültigen Datentypen. Auserdem kann man 1,5 + 3,2 + 4,3 = 9 natürlich nach Int casten...

So kriegt man es natürlich , aber bei mir werden auch Dezimalzahlen als ergebnis vorkommen..

709 Beiträge seit 2008
vor 10 Jahren

Versuch mal "Stunde DECIMAL (10,2)".

2
27sharpme Themenstarter:in
17 Beiträge seit 2013
vor 10 Jahren

Versuch mal "Stunde DECIMAL (10,2)".

Klappt leider auch nicht.

T
461 Beiträge seit 2013
vor 10 Jahren

Versuch mal alle benötigten Zeilen zum auslesen und berechne mal testweise lokal in deiner Assembly.

Wäre interessant was das Ergebnis ist...

Ich habe den Titel mal angepasst, so dass Suchende auch etwas damit anfangen können. EDIT: Ich sollte beim Wort "Shift" im Titel das "f" nicht vergessen... 😄

F
115 Beiträge seit 2012
vor 10 Jahren

aber bei mir werden auch Dezimalzahlen als ergebnis vorkommen

ja, aber kommen Sie im konkreten Testfall vor? Führ das SQL doch mal in der Konsole aus und sieh Dir das Ergebnis an. SQLite hat ja bzgl. Typen eine recht eigene Sicht auf die Welt. Anders als viele Andere DBs wird dort ja vieles als Text gespeichert und/oder implizit konvertiert...

j.

3.511 Beiträge seit 2005
vor 10 Jahren

Was heißt klappt nicht?

Beispiel


var connection = new SQLiteConnection("Data Source=:memory:;Version=3;New=True;");
connection.Open();

new SQLiteCommand("CREATE TABLE Test (col DECIMAL(10,2))", connection).ExecuteNonQuery();
new SQLiteCommand("INSERT INTO Test (col) VALUES (1)", connection).ExecuteNonQuery();
new SQLiteCommand("INSERT INTO Test (col) VALUES (2)", connection).ExecuteNonQuery();
new SQLiteCommand("INSERT INTO Test (col) VALUES (3)", connection).ExecuteNonQuery();

var result1 = new SQLiteCommand("SELECT SUM(col) FROM Test", connection).ExecuteScalar();
Console.WriteLine("{0} = {1}", result1.GetType().Name, result1);

new SQLiteCommand("DELETE FROM Test", connection).ExecuteNonQuery();

new SQLiteCommand("INSERT INTO Test (col) VALUES (1.5)", connection).ExecuteNonQuery();
new SQLiteCommand("INSERT INTO Test (col) VALUES (2.5)", connection).ExecuteNonQuery();
new SQLiteCommand("INSERT INTO Test (col) VALUES (3.5)", connection).ExecuteNonQuery();

var result2 = new SQLiteCommand("SELECT SUM(col) FROM Test", connection).ExecuteScalar();
Console.WriteLine("{0} = {1}", result2.GetType().Name, result2);

Ausgabe:


6 = Int64
7.5 = Double

Will dir ja nicht zu nahe treten, aber du solltest unbedingt an den Grundlagen zu Datenbanken und Datentypen arbeiten.

"Jedes Ding hat drei Seiten, eine positive, eine negative und eine komische." (Karl Valentin)

2
27sharpme Themenstarter:in
17 Beiträge seit 2013
vor 10 Jahren

Wenn es direkt mit INSERT INTO mache funktioniert es aber ich möchte es mit einem Steuerelement machen.

Hier versuche ich es mit nummericUpDown:

 dba.InsertValue(Datepicker.Text, Convert.ToDecimal(timeChoose.Text));

Hier nochmal wie ich es eintrage:

 public SQLiteCommand InsertValue(string date , decimal time)
        {
            SQLiteCommand command = new SQLiteCommand(connection);

            command.CommandText = String.Format("insert into Times (Datum,Stunde) values ('{0}','{1}')",
              date ,
              time);
            command.ExecuteNonQuery();

            return command;
C
2.121 Beiträge seit 2010
vor 10 Jahren

Mal ernsthaft, bevor das ganze hier geschlossen wird.
Texte kann man nicht addieren. Was soll "hallo" + "Mittwoch" ergeben?
Drauf hoffen dass die Datenbank irgendwelche Umwandlungen versucht ist extremst unsauber, auch wenn vielleicht wirklich noch was nachvollziehbares rauskommt.

Speichere deine Daten mit dem passenden Datentyp, dann stimmt auch das Ergebnis. In dem Fall wäre es ein Kommazahlen Typ, Google sagt mir bei SQLite gibt es dafür den Typ REAL.

F
10.010 Beiträge seit 2004
vor 10 Jahren

[Artikelserie] SQL: Parameter von Befehlen
Du kommst nicht zufällig von PHP?

Dann solltest du dir mal das Konzept der typsicherheit anschauen.

2
27sharpme Themenstarter:in
17 Beiträge seit 2013
vor 10 Jahren

Vielen Dank für die Antworten.

Ich weiß jetzt nur nicht wie ich die Zahlen eintragen soll , da es ja nicht mit dem Steuerelement funktioniert.

Die Daten speichere ich ja mit decimal , damit sollte es auch gehen.

T
461 Beiträge seit 2013
vor 10 Jahren
   private  SQLiteCommand  creattable()  
        {  
            SQLiteCommand command = new SQLiteCommand(connection);  
            command.CommandText = String.Format("create table if not exists {0} (" +  
                "  ID integer not null primary key autoincrement," +  
                "  Datum  date  ," +  
                "  Stunde varchar (10,2))",  
  
                "Times");  
             return command;  

Ändere mal den Typen von varchar in decimal in der Datenbank und versuche mal Beispiele ohne Steuerelemente....

Ich habe den Titel mal angepasst, so dass Suchende auch etwas damit anfangen können. EDIT: Ich sollte beim Wort "Shift" im Titel das "f" nicht vergessen... 😄

2
27sharpme Themenstarter:in
17 Beiträge seit 2013
vor 10 Jahren

Ohne Steuerelemente funktioniert das ganze auch.
Also wenn man mit Insert direkt einen Wert übergibt.

Doch so möchte ich es ja nicht.

Mit Steuerelement zeigt mir das Datagridview nur Integerwerte.
Wenn ich damit rechne wird auch Integer benutz.

T
461 Beiträge seit 2013
vor 10 Jahren

Hier versuche ich es mit nummericUpDown:

 dba.InsertValue(Datepicker.Text, Convert.ToDecimal(timeChoose.Text));  

Hab ich das richtig verstanden daß dieses 'timeChoose' so ein Steuerelement ist ?

Müßtest du dann hier nicht NumericUpDown.Value verwenden ? Value ist vom Typ ein decimal.
Man kann hier auch extra die Dezimalstellen angeben : NumericUpDown.DecimalPlaces

Ich habe den Titel mal angepasst, so dass Suchende auch etwas damit anfangen können. EDIT: Ich sollte beim Wort "Shift" im Titel das "f" nicht vergessen... 😄

C
2.121 Beiträge seit 2010
vor 10 Jahren

Du solltest dir klar machen mit welchen Teilen deines Programms du hier zu tun hast. Das wäre einmal das Programm an sich, das Werte in die Datenbank eintragen will. Dann die Datenbank, in der Werte drin stehen und dort wieder ausgelesen werden.
Wenn das was nach dem ganzen Prozess am Ende rauskommt nicht stimmt, solltest du schrittweise schauen warum. Vor allem debuggen und dir ansehen was aus dem Control ausgelesen wird und was wirklich in die DB eingetragen wird. Dann weißt du wenigstens ob die Daten nur falsch ausgelesen werden oder ob sie schon falsch eingetragen werden.

Sieh dir an was die Insert Methode tut, was die für ein SQL erzeugt. Sieh dir an was in der Tabelle steht.
Dein Problem könnte daran liegen dass du eine Kommazahl auf einem deutschen System in einen String umwandeln lässt, wo sie ein Komma bekommt statt einem Punkt. Die DB erkennt das dann falsch und trägt Müll ein.

Hinweis von herbivore vor 10 Jahren

Damit sollte nun wirklich alles gesagt sein.

Hinweis von herbivore vor 10 Jahren

Threads zusammengefügt. Die Symptome zeigen sich zwar an einer anderen Stelle, aber dahinter steckt das gleiche Problem, nämlichen das keine SQL-Parameter verwendet wurden.

2
27sharpme Themenstarter:in
17 Beiträge seit 2013
vor 10 Jahren
NummericUpDown Punkt durch Komma ersetzen ?

Hallo ,

Ich arbeite mit dem SQLite Datenbank und versuche Dezimalwerte mit nummericupdown einzutragen.

Bis dahin klappt ja alles nur bei Kommazahlen möchte er nicht.

Ich vermute , weil ich die Zahl mit Komma gebe aber die Datenbank es mit Punkt haben möchte.

z.B: 1.5 statt 1,5.

Nun aber gibt das Steuerelement nur Kommazahlen wieder.

Wie könnte ich das am besten lösen.

  • 27sharpme
C
2.121 Beiträge seit 2010
vor 10 Jahren

Mal unter uns, eine Kommazahl mit so einem Control einzugeben ist doch 10 mal umständlicher als sie einfach in eine Textbox einzutippen.

Gibt das Control wirklich einen String zurück?
Und wenn, dann willst du in einem string einen Wert replacen.
Spätestens Google sollte dir eigentlich sagen wie man das ersetzen kann. Ein bisschen selber suchen macht dich übrigens bei solchen einfachen Dingen um einiges schneller als hier zu fragen 😉

2
27sharpme Themenstarter:in
17 Beiträge seit 2013
vor 10 Jahren

Hallo ,

Das Control gibt kein String zurück , sondern ein Decimalwert.

Deswegen kann ich es auch nicht replacen.

C
2.121 Beiträge seit 2010
vor 10 Jahren

Warum versuchst du dann nicht das was man dir im letzten Beitrag schon geraten hat? Verwende Parameter um die Zahl einzutragen, dann hast du keine Probleme mit der Darstellung.
String.Format macht einen String aus der Zahl, daher das Komma.

2.207 Beiträge seit 2011
vor 10 Jahren

Ich vermute , weil ich die Zahl mit Komma gebe aber die Datenbank es mit Punkt haben möchte.

Das findest du ganz leicht mit dem Debugger und einem Blick in die DB raus.

Wie auch immer. Schaue dir bitte [Artikelserie] SQL: Parameter von Befehlen an. Spätestens da kannst du casten/replacen/parsen.

String-Operationen, casten etc. setzen wir hier als Grundlagen vorraus.

Beachte bitte [Hinweis] Wie poste ich richtig? 1.1 und 1.1.1

Coffeebean

Thema geschlossen