Firebird 2.5.5: bekomme falsche Werte aus der Datenbank

    Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

    Unsere Datenschutzerklärung wurde aktualisiert. Mit der Nutzung unseres Forums akzeptierst Du unsere Datenschutzerklärung. Du bestätigst zudem, dass Du mindestens 16 Jahre alt bist.

    • Firebird 2.5.5: bekomme falsche Werte aus der Datenbank

      Ich jage einem obskuren Fehler hinterher... ich habe eine Firebird-Datenbank und bekomme falsche Werte zurück...
      Das Feld MWert1 ist als DEC(18,2) mit 2 Nachkommazahlen korrekt angelegt und Probleme habe ich nur bei Werten kleiner 0,1. Speichere ich 1.01 ab

      Quellcode

      1. X$ = "UPDATE MAT SET MKey = '"+Esatz$[1] + "',MTyp ='"+ Esatz$[2] + "',MText ='"+ Esatz$[3] +"',MWert1 ='"+ Esatz$[4] +"',MWert2 ='"+ESatz$[5]+"', MPreis='"+ESatz$[6]+"',MDatum='"+Date$(0)+"' WHERE MPrim = "+ ESatz$[8]

      dann bekomme ich auch beim Auslesen mit

      Quellcode

      1. X$ = "SELECT MWert1 From MAT WHERE MPrim = "+ ESatz$[8]
      2. @db("fbSQLExec", ep&, X$, hGrid&)
      3. X$=@GetText$(hGrid&,0,0)
      den korrekten Wert zurück. Speichere ich aber 0,01 ab, dann finde ich in der Datenbank den korrekten Wert wenn ich mit nem externen Browser in die Datenbank reinschaue - lese ichs aber mit obigem Code aus, dann bekomme ich den Wert 0,1 zurück - was mach ich falsch?
      ---
      Xprofan X4, Win7/32, Win10/64
    • Bevor ichs in die Datenbank reinschreibe, lasse ich den Dezimaltrenner prüfen und alle eventuellen Kommaeingaben mit

      Quellcode

      1. X$ = Translate$(X$,",",".")
      umwandeln.
      Den Fehlerhaften Wert bekomm ich beim Einlesen, ich weiss nur nicht, obs was mit der Übergabe in die Grid zu tun hat...
      ---
      Xprofan X4, Win7/32, Win10/64
    • Ich habe jetzt mal nach dem Abspeichern meine Prüfroutine nicht in die Grid geladen sondern schreibe in die Listbox und lese gezielt den einzelnen Wert aus, doch auch hier bekomme ich einen falschen Wert.

      Quellcode

      1. 'Prüfroutine
      2. X$ = "SELECT MWert1 From MAT WHERE MPrim = "+ ESatz$[8]
      3. @db("fbSQLExec", ep&, X$, 1)
      4. X$ = GetString$(0,2)
      5. print #1, "Geladen: " + X$
      6. 'Ende Prüfroutine
      Es bleibt unverändert: Speichere ich 1.01 ab, bekomme ich beim Auslesen 1.01
      Speichere ich 0.94 ab, bekomme ich beim Auslesen 0.94
      Speichere ich 0.05 ab, bekomme ich beim Auslesen 0.5

      In der Datenbank steht in Wirklichkeit aber der korrekte Wert drin...
      ---
      Xprofan X4, Win7/32, Win10/64
    • ich habe jetzt mal zum testen den Code extrahiert und als eigenständig lauffähiges Programm zusammengefasst - es muss nur Firebird embedded im Hintergrund existieren. Ich erzeuge eine neue Firebird Datenbank, schreibe den Wert 0.06 rein, lese den Wert aus und schreibe ihn in eine Textdatei: da drin finde ich dann .6
      Code zum testen:

      Quellcode

      1. declare hGrid&, fbdll&, X$, ep&
      2. @Set("SQLNull","0")
      3. @Set("Errorlevel", 2)
      4. @Set("Decimals", 2)
      5. hGrid& = create("Grid", 0,0)
      6. fbdll&=db("fbUseDLL", "fbembed.dll")
      7. assign #1, "tmp.fdb"
      8. erase #1
      9. Assign #1, "tmp.log"
      10. Rewrite #1
      11. print #1, "gestartet: "+ dt("getDate", 6)
      12. ep& = db("fbCreate", "TEMP", "TEMP", "tmp.fdb")
      13. db("fbSQLExec", ep&, "create table MAT(MWert1 DEC(18,2))", 1)
      14. X$ = "INSERT INTO MAT (MWert1) VALUES ('0.06')"
      15. @db("fbSQLExec", ep&, X$, 1)
      16. 'Prüfroutine
      17. X$ = "SELECT * From MAT"
      18. @db("fbSQLExec", ep&, X$, hGrid&)
      19. X$ = GetText$(hGrid&, 0,0)
      20. print #1, "Geladen: " + X$
      21. db("fbDone", ep&)
      22. close #1
      Alles anzeigen
      ---
      Xprofan X4, Win7/32, Win10/64
    • Im Moment bin ich unterwegs, aber wenn ich zurück bin, werde ich mir das mal näher ansehen.

      Gruß
      Roland
      (Intel Duo E8400 3,0 GHz / 4 GB RAM / 250 GB HDD / ATI Radeon HD4770 512 MB / Windows Vista - ausgemustert zum Verkauf)
      AMD Athlon II X2 2,9 GHz / 8 GB RAM / 500 + 1000 GB HDD / ATI Radeon 3000 (onboard) / Windows 10(64) - XProfan X4


      http://www.xprofan.de
    • das war ein guter Typ, mit den Datentypen zu spielen. Ich hab mal den Float als Datentyp genommen und meine 0.06 in die Datenbank geschrieben, und bekam dann beim Wiedereinlesen von Firebird den String 0,0599999986588955 zurück.
      nachdem ich ja Decimals mit 2 angegeben hatte, dachte ich, ich könnte einfach den String mit VAL in eine Zahl und dann mit Str$ wieder in einen String mit 2 gerundeten Nachkommastellen umwandeln, hab da aber nicht mit der Tücke des Dezimaltrenners gerechnet, denn mein String war 0.00
      Erst nach Einsatz von Translate auf den String und dann die Typumwandlung komm ich auf mein 0.06... hier der Code:

      Quellcode

      1. declare hGrid&, fbdll&, X$, Y$, ep&, x!, y!
      2. @Set("SQLNull","0")
      3. @Set("Errorlevel", 2)
      4. @Set("Decimals", 2)
      5. hGrid& = create("Grid", 0,0)
      6. fbdll&=db("fbUseDLL", "fbembed.dll")
      7. assign #1, "tmp.fdb"
      8. erase #1
      9. Assign #1, "tmp.log"
      10. Rewrite #1
      11. print #1, "gestartet: "+ dt("getDate", 6)
      12. ep& = db("fbCreate", "TEMP", "TEMP", "tmp.fdb")
      13. 'db("fbSQLExec", ep&, "create table MAT(MWert1 DEC(18,2))", 1)
      14. db("fbSQLExec", ep&, "create table MAT(MWert1 FLOAT)", 1)
      15. X$ = "INSERT INTO MAT (MWert1) VALUES ('0.06')"
      16. @db("fbSQLExec", ep&, X$, 1)
      17. 'Prüfroutine
      18. X$ = "SELECT * From MAT"
      19. @db("fbSQLExec", ep&, X$, hGrid&)
      20. X$ = GetText$(hGrid&, 0,0)
      21. print #1, "Geladen: " + X$
      22. y! = val(X$)
      23. Y$ = str$(y!)
      24. print #1, "umgewandelt: " + Y$
      25. X$ = Translate$(X$,",", ".")
      26. x! = Val(X$)
      27. X$ = Str$(X!)
      28. print #1, "Translated: " + X$
      29. db("fbDone", ep&)
      30. close #1
      Alles anzeigen
      und meine Logdatei hat dann bei mir nach start folgende Einträge:

      gestartet: 08.02.2017 16:56:55
      Geladen: 0,0599999986588955
      umgewandelt: 0.00
      Translated: 0.06

      vielleicht hat jemand ne einfachere Variante...
      ---
      Xprofan X4, Win7/32, Win10/64
    • Vielleicht noch ne andere Frage :
      Verarbeitest du wirklich so große Zahlen ?
      Du hast 18 Stellen vor dem Komma und zwei
      für Dezimal. Da wäre ja Platz für Trilliarden
      und noch mehr.
      z.B. für bis zu 99.999,99 reichen eigentlich
      8 Stellen. Das sind fast Hunderttausend.
      Soviel ich weiß, muß man den Dezimaltrenner
      mitzählen.

      Bei XProfan ist die Rechengenauigkeit bei etwa
      15 Stellen. Also, ich würde da nur so viele Stellen
      reservieren, wie du maximal erwartest bzw. was
      Sinn macht.
    • also ich habs jetzt mal in der DB mit DEC(5,2) getestet und bekomme auch da den falschen Wert beim Laden zurück: In der Datenbank steht 0.06, XProfan meldet mir nach dem Laden 0.6 - irgendwo muss da noch ein Wurm sitzen - mal gespannt, ob Roland die Nuss knackt.
      ---
      Xprofan X4, Win7/32, Win10/64
    • So, jetzt habe ich Zeit gefunden:

      Da ist tatsächlich ein Bug im Programm: Firebird speichert die Typen DEC (bzw. DECIMAL) und NUMERIC intern als Integer mit Angabe der Nachkommastellen. In meiner Umwandlungsroutine, die den Dezimalpunkt wieder einfügt, hatte sich ein Fehler eingeschlichen, wenn nach dem Dezimalpunkt die erste Ziffer (oder die ersten Ziffern) eine "0" waren. In der nächsten Version ist der Fehler behoben.

      Workaround bis dahin: Den Datentyp FLOAT oder besser DOUBLE PRECISION wählen:

      Quellcode

      1. cls
      2. declare fbdll&, X$, ep&
      3. @Set("SQLNull","0")
      4. @Set("Errorlevel", 2)
      5. @Set("Decimals", 2)
      6. fbdll&=db("fbUseDLL", "fbembed.dll")
      7. assign #1, "tmp.fdb"
      8. erase #1
      9. print "gestartet: " + dt("getDate", 6)
      10. ep& = db("fbCreate", "TEMP", "TEMP", "tmp.fdb")
      11. db("fbSQLExec", ep&, "create table MAT(MWert1 DOUBLE PRECISION)", 0)
      12. X$ = "INSERT INTO MAT (MWert1) VALUES (0.06)"
      13. @db("fbSQLExec", ep&, X$, 0)
      14. 'Prüfroutine
      15. X$ = "SELECT * From MAT"
      16. @db("fbSQLExec", ep&, X$, 0)
      17. db("fbDone", ep&)
      18. close #1
      19. waitinput
      20. end
      Alles anzeigen
      Da hier keine Nachkommastellen angegeben werden können, kann man das Ergebnis mit ROUND() auf die entsprechende Anzahl Nachkommastellen runden.

      Gruß
      Roland
      (Intel Duo E8400 3,0 GHz / 4 GB RAM / 250 GB HDD / ATI Radeon HD4770 512 MB / Windows Vista - ausgemustert zum Verkauf)
      AMD Athlon II X2 2,9 GHz / 8 GB RAM / 500 + 1000 GB HDD / ATI Radeon 3000 (onboard) / Windows 10(64) - XProfan X4


      http://www.xprofan.de