WernerK: Geldbeträge in DB speichern

Hallo
in einer MySQL Tabelle ist eine Spalte "salary" als decimal(10,0) definiert.
Wenn man nun in einer PHP Webseite die ein Textfeld "Geldbetrag" enthält speichert und hier jemand z.b. 50.000 eingibt, dann wird nur der Wert 50 in der DB gespeichert.

Wie macht ihr so etwas?
Ist der Datentyp decimal ok oder sollte man als "varchar" speichern?

Sollte man eine Eingabe mit Punkt verbieten?

Bin für jeden Tipp dankbar.

Gruss
Werner

  1. Hello,

    in einer MySQL Tabelle ist eine Spalte "salary" als decimal(10,0) definiert.
    Wenn man nun in einer PHP Webseite die ein Textfeld "Geldbetrag" enthält speichert und hier jemand z.b. 50.000 eingibt, dann wird nur der Wert 50 in der DB gespeichert.

    Wie macht ihr so etwas?
    Ist der Datentyp decimal ok oder sollte man als "varchar" speichern?

    Sollte man eine Eingabe mit Punkt verbieten?

    Man sollte am Server Input-Filter verwenden und dem User an Client genau aufzeigen, wie er die Daten eingeben soll.

    Das ist dann ja auch eine Frage der LOCALE's, mit denen man auch das Money-Format festlegen kann. Aber bevor Du dich da durch alle Schnittstellen durchgehangelt hast, ist ein Inputfilter einfacher.

    Die Daten kommen in PHP entweder als String oder als Array of Strings an. Die Umwandlung der Datenrepräsentation in Datentypen muss dann erst wieder vorgenommen werden.

    Ein paar vorbereitete Filter hat PHP schon:
    http://de1.php.net/manual/en/filter.filters.sanitize.php

    oder eine Funktion:
    http://de1.php.net/manual/en/function.number-format.php

    Am Client kann man ggf. auch mittels JavaScript etwas nachhelfen.

    oder mit CSS?
    http://wiki.csswg.org/ideas/content-formatting
    Das war zumindest mal ein Vorschlag.

    Und HTML5 müsste auch noch Möglichkeiten kennen, die ich noch nicht ergründet habe.
    http://html5doctor.com/html5-forms-input-types/#input-number

    usw. usw.

    Der User sollte die eingebebenen Daten vor dem Eintrag in die Datenbank nochmal zur Kontrolle vorgelegt bekommen. -> Forums-Suche: Affenformular

    Liebe Grüße aus dem schönen Oberharz

    Tom vom Berg

    --
     ☻_
    /▌
    / \ Nur selber lernen macht schlau
    http://bikers-lodge.com
    1. Hallo

      also ich würde als Anwender den Geldbertrag "Fünzigtausend" als
      50.000 eingeben.
      Das bedeutet dann also man müsste vor dem Speichern in der MySQL DB den Punkt entfernen damit er als 50000 gespeichert wird?

      Wenn nun aber jemand 50,000 eingibt wird auch der Wert 50 gespeichert.
      Also müsste man auch verhindern das ein Komma eingegeben wird?

      Und wenn nun jemand Fünfzigtausend und 55 Cent so eingeben will
      50000,55 dann steht in der DB mit decimal(10,0) später nur 50000 drin.

      Wie löst man all dies am besten? Also den Punkt rausfiltern mit str_replace oder ähnlichem ist kein Problem.
      Aber die anderen Situationen? Oder ist der Typ decimal(10,0) falsch gewählt?

      Gruss
      Werner

      1. machs doch ganz einfach -> gib die eingabe vor:
        mach zwei input felder in der mitte ein Komma und dahinter ein €.

        die felder kannst du auch schon mit 0 bzw 00 vorfüllen (value) ->
        dann kommt der user nicht drumrum richtig zeug einzugeben

        danach setz sie zusammen:

        $preis = $input1 . "." . $input2;

        Was sagte Einstein:
        Nicht alles was einfach ist, ist genial, aber alles was genial ist, ist einfach ;-)

        Viele Grüße aus LA

        --
        ralphi
        1. Hallo,

          machs doch ganz einfach -> gib die eingabe vor:
          mach zwei input felder in der mitte ein Komma und dahinter ein €.

          Aus Usersicht ist das imho die schlechteste Lösung. Man sollte niemals aus Faulheit (weil man zu faul ist die Eingaben richtig zu behandeln) den User zwingen Daten auf umständliche Art einzugeben.

          Gruß,
          Tobias

      2. Hallo

        also ich würde als Anwender den Geldbertrag "Fünzigtausend" als
        50.000 eingeben.

        Ich bin noch nie auf die Idee gekommen, bei einer _Eingabe_ den Tausendertrennpunkt mitanzugeben. Der ist in meinen Augen nur bei der _Ausgabe_ nützlich.

        Gruß
        Kalk

      3. Hello,

        Wie löst man all dies am besten? Also den Punkt rausfiltern mit str_replace oder ähnlichem ist kein Problem.
        Aber die anderen Situationen? Oder ist der Typ decimal(10,0) falsch gewählt?

        Es gibt sooooviele Links zu dem Thema, dass man da bestimmt noch besseres findet.
        Schau doch einfach mal in dein Internet-Banking, wie die das da machen.

        Ub der Typ decimal(10,0) falsch ist, kann ich Dir nicht beantworten. Aber er wäre für Geldbeträge ungewöhnlich. Da wäre Decimal(10,2) schon üblicher.

        Für deutsche Verhältnisse würde ich in der Eingabe übrigens das Komma als Dezimaltrenner benutzen. Das sitzt nämlich am deutschen Ziffernblock. Schau also ruhig auch mal in den Request-Header, welche Sprache bevorzugt wird.

        Für die Datenbank muss man das dann selbstverständlich passend umformatieren vor dem Speichern und nach dem Auslesen auch, bevor man es ins Value-Attribut schreibt.

        Hast Du schon mal den Input-Type mit pattern für HTML5 ausprobiert, was der taugt?

        Liebe Grüße aus dem schönen Oberharz

        Tom vom Berg

        --
         ☻_
        /▌
        / \ Nur selber lernen macht schlau
        http://bikers-lodge.com
      4. Tach!

        Wie löst man all dies am besten? Also den Punkt rausfiltern mit str_replace oder ähnlichem ist kein Problem.

        Das Stichwort heißt normalisieren. Du gibst lokalisiert Zahlen ein und dabei werden je nach Kultur unterschiedliche Zeichen verwendet. Computer-Sprache ist aber vom Englischen abgeleitet und dazu müssen eben nationale Zahlendarstellungen ins nahezu englische Format konvertiert werden. Das heißt konkret, Dezimalzeichen ist der Punkt, Tausendertrenner gibt es nicht.

        Man kann nun dahergehen und den Tausendertrenner entfernen als auch das lokale Dezimalzeichen durch einen Punkt ersetzen. Oder man nimmt sowieso ein Framework, da ist oftmals ein I18N-Komponenten drin, die Normalisierung und das Gegenteil Formatierung auch noch für andere Kulturkreise beherrscht.

        dedlfix.

      5. Hallo

        Und wenn nun jemand Fünfzigtausend und 55 Cent so eingeben will
        50000,55 dann steht in der DB mit decimal(10,0) später nur 50000 drin.

        Was sagt dir das Format Decimal(10,0)?

        Ich zitiere mal aus der Doku:

        <zitat>
        Die Deklarationssyntax für eine DECIMAL-Spalte lautet DECIMAL(M,D). Die Argumente haben in MySQL 5.1 folgende Wertebereiche:

        • M ist die Höchstzahl der Stellen (die Genauigkeit) und liegt zwischen 1 und 65. (Ältere Versionen von MySQL hatten hier einen zulässigen Wertebereich von 1 bis 254.)

        • D ist die Anzahl der Stellen rechts vom Dezimalpunkt (die Dezimalstellen) mit dem Wertebereich 0 bis 30. D darf nicht größer als M sein.
          </zitat>

        Du speicherst also mit maximal 10 Stellen, von denen keine hinter dem Dezimaltrenner stehen darf.

        Oder ist der Typ decimal(10,0) falsch gewählt?

        Frage beantwortet?

        Tschö, Auge

        --
        Verschiedene Glocken läuteten in der Stadt, und jede von ihnen vertrat eine ganz persönliche Meinung darüber, wann es Mitternacht war.
        Terry Pratchett, "Wachen! Wachen!"
        ie:{ fl:| br:> va:) ls:[ fo:) rl:( ss:| de:> js:| zu:}
        Veranstaltungsdatenbank Vdb 0.3
  2. Hi

    Wenn man nun in einer PHP Webseite die ein Textfeld "Geldbetrag" enthält speichert und hier jemand z.b. 50.000 eingibt, dann wird nur der Wert 50 in der DB gespeichert.

    wenn der Punkt der einzig mögliche 'Eingabefehler' sein kann, gehts recht einfach:

    $Betrag = str_replace(".", "", $Eingabe);

    damit löscht du den Punkt.

    Viele Grüße aus LA

    --
    ralphi
  3. Hallo

    in einer MySQL Tabelle ist eine Spalte "salary" als decimal(10,0) definiert.
    Wenn man nun in einer PHP Webseite die ein Textfeld "Geldbetrag" enthält speichert und hier jemand z.b. 50.000 eingibt, dann wird nur der Wert 50 in der DB gespeichert.

    Ist der Datentyp decimal ok oder sollte man als "varchar" speichern?

    Ja, decimal ist schon richtig. Es ist nur wichtig, zu wissen, welches Zeichen welche Bedeutung hat.

    Sollte man eine Eingabe mit Punkt verbieten?

    Der Wert, der bei dir 50.000 (fünfzigtausend) beträgt, wird in der Datenbank als 50 gespeichert, weil der Punkt in der englischen Sprache der Dezimaltrenner ist (in Deutschland ist dies das Komma). Du musst also die Eingabe des Punktes verhindern oder den Eingabewert prüfen. Bei ersterem vergrätzt du ohne weitere Erklärung die Nutzer, bei letzterem musst du mit Annahmen arbeiten, die falsch sein können. Inwieweit die im Zweifelsfalle wiederholte Nachfrage, ob diese oder jene Interpretation richtig ist, nutzerseitig zu Nervereien führt, musst du sehen (und hernach zu vermeiden suchen).

    Tschö, Auge

    --
    Verschiedene Glocken läuteten in der Stadt, und jede von ihnen vertrat eine ganz persönliche Meinung darüber, wann es Mitternacht war.
    Terry Pratchett, "Wachen! Wachen!"
    ie:{ fl:| br:> va:) ls:[ fo:) rl:( ss:| de:> js:| zu:}
    Veranstaltungsdatenbank Vdb 0.3
  4. Hello,

    Für die Clien-Seite gibt es hier ein paar nette JavaScript-Lösungen

    http://stackoverflow.com/questions/149055/how-can-i-format-numbers-as-money-in-javascript

    Auf dem Server musst Du selbstverständlich nochmal prüfen, ob es passt.

    Liebe Grüße aus dem schönen Oberharz

    Tom vom Berg

    --
     ☻_
    /▌
    / \ Nur selber lernen macht schlau
    http://bikers-lodge.com
  5. Ein ziemlich ekliges Problem das sicher sehr viele kennen :-)
    Ich hab es schon so gelöst, Tausendertrennzeichen wird verboten und Punkt UND Komma werden als Dezimaltrennzeichen behandelt. Dazu wird das Komma in einen Punkt replaced und dieses dann an eine Umwandlungsfunktion (String -> Zahl) übergeben.
    Würde auch in manchen Smartphone Apps Sinn machen, in denen auf der numerischen Tastatur das Komma nicht so einfach zu finden ist!

    Wenn fälschlicherweise ein Tausendertrennzeichen und ein Dezimaltrennzeichen angegeben sind, knallt es hierbei automatisch. Man könnte noch prüfen ob nach dem Trennzeichen mehr als zwei Stellen sind, das ist dann normalerweise auch ein Fehler.
    Und natürlich nach der Eingabe nochmal eine Bestätigung anzeigen, in der der Betrag so erscheint wie er erkannt wurde.