Messwerte aus Textbox zu MySQL - Trennzeichen geht verloren

  • VB.NET

Es gibt 10 Antworten in diesem Thema. Der letzte Beitrag () ist von Haudruferzappeltnoch.

    Messwerte aus Textbox zu MySQL - Trennzeichen geht verloren

    Hallo,

    ich möchte Messwerte aus meinen Textboxen in eine DB einfügen, die beispielsweise wie folgt aussehen:

    0,63546085357666
    236,8842
    311,84
    -0,4459281

    Nun kommen bei mir mehrere Probleme auf. Im MySQL erwarte ich Werte vom Typ DOUBLE.

    Ich konvertiere also meine Textboxen mit CDbl und übergebe sie.
    Beim INSERT-Befehl kommt die Meldung: Data truncated for column '...' at row 1.
    Also habe ich den Befehl .Replace(",", ".") genutzt, um das Komma durch einen Punkt zu ersetzen. Die Folge - die Daten kommen nun in der Tabelle an.

    Allerdings kommen die Werte nicht mit dem Punkt an, also -0.4459281, 311.84 usw., sondern so:

    63546085357666
    2368842
    31184
    -4459281

    Ich vermute, dass die Ursache in CDbl liegt.

    Kann mir jemand auf die Sprünge helfen?

    Codeauszug (etwas gekürzt und angepasst, da meine Values eigentlich übergeben werden und nicht die Textbox direkt darin steht):

    VB.NET-Quellcode

    1. ...
    2. tbTHDSpannungL1.Text = ModbusClient.ConvertRegistersToFloat(modbusClient.ReadHoldingRegisters(21329, 2), RegisterOrder.HighLow).ToString.Replace(",", ".")
    3. ...
    4. cmd.CommandText = "INSERT INTO " & "`" & schema & "`.`" & table & "`" & " (... `THDSpannungL1`, ...) VALUES (... '" & CDbl(THDSpannungL1.Text) & "' ... "');"
    5. ...
    Hallo,
    du solltest die Werte aus deinen Textboxen parsen. Beim Parsen kannst du mitgeben, in welchem Format deine Werte sind.
    Beispiel:

    C#-Quellcode

    1. const string v = "-0,4459281";
    2. double d = double.Parse(v, System.Globalization.NumberStyles.Float, new System.Globalization.CultureInfo(1031));
    3. Console.WriteLine(d);


    Und um es wieder in einen String zu wandeln, die vom MySQL-Server verstanden werden:

    C#-Quellcode

    1. ​d.ToString(System.Globalization.CultureInfo.InvariantCulture);
    @ISliceUrPanties
    Danke für den Tipp. Ich habe es mal nach deinem Beispiel versucht. Er meckert immer wieder: System.FormatException: "Die Eingabezeichenfolge hat das falsche Format."

    Es liegt definitiv an Numberstyles.Float, da er beim Typ .Any nicht meckert.
    Ich habe kurzerhand im MySQL alle Werte von Double auf Float umgestellt, leider ohne Erfolg.
    Da ja die CultureInfo dabei ist habe ich es auch nochmal jeweils mit Punkt und Komma getestet, auch ohne Änderung.

    Murdersquad schrieb:

    cmd.CommandText = "INSERT INTO " & "`" & schema & "`.`" & table & "`" & " (... `THDSpannungL1`, ...) VALUES (... '" & CDbl(THDSpannungL1.Text) & "' ... "');"


    M.E. solltest Du die einfachen Hochkommas um den Wert CDbl(THDSpannungL1.Text) weglassen.

    VB.NET-Quellcode

    1. ​cmd.CommandText = "INSERT INTO " & "`" & schema & "`.`" & table & "`" & " (... `THDSpannungL1`, ...) VALUES (... " & CDbl(THDSpannungL1.Text) & " ... "');
    NB. Es ist doch schön, wenn man lesbare Namen vergibt. Siehe auch [VB.NET] Beispiele für guten und schlechten Code (Stil).

    Murdersquad schrieb:

    Ich habe kurzerhand im MySQL alle Werte von Double auf Float umgestellt

    Das hättest du nicht machen brauchen, da NumberStyles.Float der Parse-Funktion nur sagt, was alles für Zeichen in der Zahl vorkommen könnten. Das hat nichts mit dem Datentypen zu tun. Mit welcher Zeichenfolge hast du denn jetzt genau das Problem?

    Aber was anderes. Warum baust du dir das SQL so hässlich zusammen? Auch mit dem MySQL-Connector kann man mit Parametern arbeiten. Das verhindert dann auch gleich die Möglichkeit einer SQL-Injection. Ich bin mir ziemlich sicher, dass du dann den geparsten Wert einfach nur der Funktion übergeben musst.

    C#-Quellcode

    1. ​cmd.CommandText = "INSERT INTO data (some_field) VALUES (@p)";
    2. cmd.Parameters.AddWithValue("p", 123.45);
    Ja, ich bin nicht der Profi-VB.NET/SQL-ler, ich komme eigentlich aus der SPS-Programmierung etc. :S

    Mein Command-String ist wirklich hässlich, wenn ich deinen Tipp sehe, aber ich generiere den meist schon während des Programmierens im Excel mit, daher fehlen auch die Absätze mit ( _). Aber ich werde es noch anpassen, da deine Variante deutlich übersichtlicher ist.

    Übergeben werden die Werte mit Punkt, siehe Foto.

    VB.NET-Quellcode

    1. sql_Eintrag_in_DB(txtS2.Text, txtT2.Text, Double.Parse(tbStromL1.Text), Double.Parse(tbStromL2.Text), Double.Parse(tbStromL3.Text), Double.Parse(tbStromAVGtotal.Text), Double.Parse(tbSpannungL1.Text), Double.Parse(tbSpannungL2.Text), Double.Parse(tbSpannungL3.Text), Double.Parse(tbSpannungL1L2.Text), Double.Parse(tbSpannungL2L3.Text), Double.Parse(tbSpannungL3L1.Text), Double.Parse(tbTHDStromL1.Text), Double.Parse(tbTHDStromL2.Text), Double.Parse(tbTHDStromL3.Text), Double.Parse(tbTHDSpannungL1.Text), Double.Parse(tbTHDSpannungL2.Text), Double.Parse(tbTHDSpannungL3.Text), Double.Parse(tbTHDSpannungL1L2.Text), Double.Parse(tbTHDSpannungL2L3.Text), Double.Parse(tbTHDSpannungL3L1.Text), Double.Parse(tbFrequenz.Text), Double.Parse(tbStromMaxL1.Text), Double.Parse(tbStromMaxL2.Text), Double.Parse(tbStromMaxL3.Text), Double.Parse(tbSpannungMaxL1.Text), Double.Parse(tbSpannungMaxL2.Text), Double.Parse(tbSpannungMaxL3.Text), Double.Parse(tbSpannungMaxL1L2.Text), Double.Parse(tbSpannungMaxL2L3.Text), Double.Parse(tbSpannungMaxL3L1.Text), Double.Parse(tbWirkleistungL1.Text), Double.Parse(tbWirkleistungL2.Text), Double.Parse(tbWirkleistungL3.Text), Double.Parse(tbWirkleistungtotal.Text), Double.Parse(tbBlindleistungL1.Text), Double.Parse(tbBlindleistungL2.Text), Double.Parse(tbBlindleistungL3.Text), Double.Parse(tbBlindleistungtotal.Text), Double.Parse(tbScheinleistungL1.Text), Double.Parse(tbScheinleistungL2.Text), Double.Parse(tbScheinleistungL3.Text), Double.Parse(tbScheinleistungtotal.Text), Double.Parse(tbLeistungsfaktorL1.Text), Double.Parse(tbLeistungsfaktorL2.Text), Double.Parse(tbLeistungsfaktorL3.Text), Double.Parse(tbLeistungsfaktortotal.Text), Double.Parse(tbWirkenergieP.Text), Double.Parse(tbWirkenergieM.Text), Double.Parse(tbBlindenergieP.Text), Double.Parse(tbBlindenergieM.Text), Double.Parse(tbScheinenergieP.Text), tbBemerkung.Text)
    2. cmd.CommandText = "INSERT INTO " & "`" & schema & "`.`" & table & "`" & " (`StromL1`, `StromL2`, `StromL3`, `StromAVG`, `SpannungL1`, `SpannungL2`, `SpannungL3`, `SpannungL1-L2`, `SpannungL2-L3`, `SpannungL3-L1`, `THDStromL1`, `THDStromL2`, `THDStromL3`, `THDSpannungL1`, `THDSpannungL2`, `THDSpannungL3`, `THDSpannungL1-L2`, `THDSpannungL2-L3`, `THDSpannungL3-L1`, `Frequenz`, `StromL1max`, `StromL2max`, `StromL3max`, `SpannungL1max`, `SpannungL2max`, `SpannungL3max`, `SpannungL1-L2max`, `SpannungL2-L3max`, `SpannungL3-L1max`, `WirkleistungL1`, `WirkleistungL2`, `WirkleistungL3`, `Wirkleistungtotal`, `BlindleistungL1`, `BlindleistungL2`, `BlindleistungL3`, `Blindleistungtotal`, `ScheinleistungL1`, `ScheinleistungL2`, `ScheinleistungL3`, `Scheinleistungtotal`, `LeistungsfaktorL1`, `LeistungsfaktorL2`, `LeistungsfaktorL3`, `Leistungsfaktortotal`, `WirkenergieP`, `WirkenergieM`, `BlindenergieP`, `BlindenergieM`, `Scheinenergie`, `Bemerkung`, `Zeitstempel`) VALUES ('" & Eintrag_01 & "' , '" & Eintrag_02 & "' , '" & Eintrag_03 & "' , '" & Eintrag_04 & "' , '" & Eintrag_05 & "' , '" & Eintrag_06 & "' , '" & Eintrag_07 & "' , '" & Eintrag_08 & "' , '" & Eintrag_09 & "' , '" & Eintrag_10 & "' , '" & Eintrag_11 & "' , '" & Eintrag_12 & "' , '" & Eintrag_13 & "' , '" & Eintrag_14 & "' , '" & Eintrag_15 & "' , '" & Eintrag_16 & "' , '" & Eintrag_17 & "' , '" & Eintrag_18 & "' , '" & Eintrag_19 & "' , '" & Eintrag_20 & "' , '" & Eintrag_21 & "' , '" & Eintrag_22 & "' , '" & Eintrag_23 & "' , '" & Eintrag_24 & "' , '" & Eintrag_25 & "' , '" & Eintrag_26 & "' , '" & Eintrag_27 & "' , '" & Eintrag_28 & "' , '" & Eintrag_29 & "' , '" & Eintrag_30 & "' , '" & Eintrag_31 & "' , '" & Eintrag_32 & "' , '" & Eintrag_33 & "' , '" & Eintrag_34 & "' , '" & Eintrag_35 & "' , '" & Eintrag_36 & "' , '" & Eintrag_37 & "' , '" & Eintrag_38 & "' , '" & Eintrag_39 & "' , '" & Eintrag_40 & "' , '" & Eintrag_41 & "' , '" & Eintrag_42 & "' , '" & Eintrag_43 & "' , '" & Eintrag_44 & "' , '" & Eintrag_45 & "' , '" & Eintrag_46 & "' , '" & Eintrag_47 & "' , '" & Eintrag_48 & "' , '" & Eintrag_49 & "' , '" & Eintrag_50 & "' , '" & Eintrag_51 & "' , '" & Format(Date.Now, "yyyy-MM-dd HH:mm:ss") & "');"
    Bilder
    • Register.png

      95,31 kB, 561×856, 52 mal angesehen
    Das Arbeiten mit den SQL Command Parametern löst dieses (und andere) Probleme. Siehe Post von @ISliceUrPanties
    "Gib einem Mann einen Fisch und du ernährst ihn für einen Tag. Lehre einen Mann zu fischen und du ernährst ihn für sein Leben."

    Wie debugge ich richtig? => Debuggen, Fehler finden und beseitigen
    Wie man VisualStudio nutzt? => VisualStudio richtig nutzen
    Also ich habe den Code angepasst und die Command Parameter verwendet.

    Komischerweise habe ich dann im Debugger gesehen, dass die Werte nach dem Parsen ohne Komma in der Funktion für den SQL-Eintrag kamen.
    Ich habe dann ToString.Replace(",", ".") entfernt und alles lief wunderbar.

    Wieder etwas gelernt.
    Da kann der Replace aber nicht schuld dran sein, wo keine Kommas sind macht der auch keine weg. Deine Werte haben ja wie du oben sagtest einen Punkt.
    Dann wirst du den noch irgendwie anders entfernt haben, beim Überarbeiten der Methode.

    Das einzige was mir einfiele warum das Entfernen von Replace eine Wirkung hat ist, wenn du es auf den gesamten Insert-Befehl anwendest, das haut natürlich auch die Kommas weg die du brauchst.