hawkmaster: Preise in DB speichern, Datentyp

Hallo zusammen,

ich möchte Preise in einer DB speichern.
Also z.b.
350,00
467,99

Was ist die gängige Praxis für den Datentyp

Bei MySQl würde ich event. decimal(10,2) nehmen

Bei SQLite numeric(10,2)

Ich habe aber auch schon Beiträge gesehen, wo empfohlen wurde einen Integer zu nehmen und die
Beträge in Cent umzurechnen.
Macht das Sinn?

Wie würdet ihr das machen?

vielen Dank und viele Grüße
hawk

  1. Tach!

    ich möchte Preise in einer DB speichern.
    Was ist die gängige Praxis für den Datentyp
    Bei MySQl würde ich event. decimal(10,2) nehmen
    Bei SQLite numeric(10,2)

    Genau das. Oder andere Typen, die mit exakten Zahlen rechnen und keine Rundungsfehler wegen des Dualsystems aufweisen.

    Ich habe aber auch schon Beiträge gesehen, wo empfohlen wurde einen Integer zu nehmen und die Beträge in Cent umzurechnen. Macht das Sinn?

    Generell nicht. In Fällen wo kein Dezimal-/Money-Typ zur Verfügung steht, kann das eine Notlösung sein, mehr aber auch nicht.

    dedlfix.

    1. Aloha ;)

      Generell nicht. In Fällen wo kein Dezimal-/Money-Typ zur Verfügung steht, kann das eine Notlösung sein, mehr aber auch nicht.

      Die Numerik sagt aber: präzise ist anders. Siehe mein Post. Allenfalls zum Speichern kann man Dezimaldarstellung wählen, zum ganz präzisen Rechnen sollte man aber wohl Integer verwenden.

      Habe in Form einer Matlab-Übung Auslöschung schon erlebt... und das ist kein Spaß :D vor allem nicht, wenns mit Geld passiert :D

      Grüße,

      RIDER

      --
      Camping_RIDER a.k.a. Riders Flame a.k.a. Janosch Zoller
      ch:? rl:| br:> n4:? ie:% mo:| va:) js:) de:> zu:) fl:( ss:| ls:[
      1. Tach!

        Generell nicht. In Fällen wo kein Dezimal-/Money-Typ zur Verfügung steht, kann das eine Notlösung sein, mehr aber auch nicht.

        Die Numerik sagt aber: präzise ist anders. Siehe mein Post. Allenfalls zum Speichern kann man Dezimaldarstellung wählen, zum ganz präzisen Rechnen sollte man aber wohl Integer verwenden.

        Die Datentypen Decimal (anderenorts auch Money genannt) sind extra für das exakte Rechnen im Dezimalsystem ausgelegt. Die haben die Rundungsprobleme von Floats nicht. Deshalb sind sie ja für finanzielle Operationen geeignet. Und da sind sie auch besser als Integer, weil sie die Nachkommastellen ordentlich verwalten und nicht von und nach Integer hin- und hergerechnet werden muss.

        dedlfix.

        1. Aloha ;)

          Die Datentypen Decimal (anderenorts auch Money genannt) sind extra für das exakte Rechnen im Dezimalsystem ausgelegt. Die haben die Rundungsprobleme von Floats nicht. Deshalb sind sie ja für finanzielle Operationen geeignet. Und da sind sie auch besser als Integer, weil sie die Nachkommastellen ordentlich verwalten und nicht von und nach Integer hin- und hergerechnet werden muss.

          Okay, mein Unwissen straft mich. Ich hatte Decimal mit float gedanklich gleichgesetzt.

          Trotzdem -  wird beim Speichern als decimal im verarbeitenden System - also bspw. PHP - nicht gleich float draus, sobald ich den Wert aus der Datenbank abgerufen habe?

          Das bedeutet doch, dass ich dann bei Speichern als decimal an dieser Stelle höllisch aufpassen muss, um nicht mit float weiterzurechnen. Oder bin ich da gedanklich auf dem Holzweg?

          Oder kennt PHP eine Entsprechung zu decimal ungleich float? Wäre mir zumindest bisher nicht bekannt. Wenn nicht wäre es vllt. zugunsten der vielseitigen Einbindbarkeit der Datenbank doch wieder günstig als Integer zu speichern...

          Grüße,

          RIDER

          --
          Camping_RIDER a.k.a. Riders Flame a.k.a. Janosch Zoller
          ch:? rl:| br:> n4:? ie:% mo:| va:) js:) de:> zu:) fl:( ss:| ls:[
          1. Tach!

            Trotzdem -  wird beim Speichern als decimal im verarbeitenden System - also bspw. PHP - nicht gleich float draus, sobald ich den Wert aus der Datenbank abgerufen habe?

            Das weiß ich grad nicht, kann mir das aber nicht vorstellen. Jedenfalls mysqli_fetch_assoc() sagt, es würde Strings liefern.

            Das bedeutet doch, dass ich dann bei Speichern als decimal an dieser Stelle höllisch aufpassen muss, um nicht mit float weiterzurechnen. Oder bin ich da gedanklich auf dem Holzweg?

            Du kannst dann keine PHP-eigenen Rechenoperationen verwenden, ohne Verlustgefahr zu haben. Aber es gibt die Extensions BCMath und GMP zum Lösen des Problems. Ob nun höllisch oder anders - beim Programmieren muss man immer aufpassen. Auch in anderen Sprachen muss man aufpassen, dass es Decimal bleibt und keine Funktion das nach Float konvertiert. (Bei typsicheren Sprachen kann einem das die IDE gleich sagen, aber das ist ein anderes Thema.)

            dedlfix.

  2. Aloha ;)

    Ich habe aber auch schon Beiträge gesehen, wo empfohlen wurde einen Integer zu nehmen und die
    Beträge in Cent umzurechnen.
    Macht das Sinn?

    Das macht genausowenig Sinn wie alles andere.

    Sinnvoll könnte die Methode trotzdem sein. Einfach deshalb, weil Integer der einfachst mögliche Zahlentyp ist. Weiterhin möchtest du die Ausgabe vielleicht dahingehend kontrollieren, welche Dezimalzeichentrennung genutzt wird. Je nach System, das die Datenbank nachher verwenden soll, ist das dort mit Integern unter Umständen einfacher - zumal Geldbeträge immer exakt zwei Nachkommastellen besitzen.

    Fließkommaoperationen sind in Computersystemen grundsätzlich problematisch (Effekte wie Auslöschung und Co.) - auch wenn das in deinem Fall wahrscheinlich oft keine Rolle spielt (so extrem viele Stellen sind bei Geldwerten nicht vorstellbar).

    Wie würdet ihr das machen?

    Unter verlinkter Wikipediaseite zur Gleitkommazahl findest du den Grund, warum Finanzmathematik nicht mit Gleitkommaoperationen gemacht wird, unter Dezimalzahlen.

    Aufgrund der vielen Gründe, keine Gleitkommazahlen für Finanzen zu verwenden (möge die Wahrscheinlichkeit, dass ein Fehler auftritt, aucb noch so gering sein) und wegen dem geringen Aufwand (direkt vor der Ausgabe, also nach der Rechnung, kann einfach stur durch 100 geteilt werden) würde ICH mich für Integer entscheiden. Hatte mir vor deinem Thread darüber aber auch noch nie Gedanken gemacht.

    Grüße,

    RIDER

    P.S.: An CK und Matthias Apsel - ihr seht an meinem Link oben, dass das Link-Parsen zumindest hier noch nicht immer ordentlich geht. Wahrscheinlich hätte ich die URI-encodete Variante nehmen müssen, dazu war ich aber zu faul. Und 0815-User weiß nicht wie das geht. Oder hab ich was anderes falsch gemacht?

    --
    Camping_RIDER a.k.a. Riders Flame a.k.a. Janosch Zoller
    ch:? rl:| br:> n4:? ie:% mo:| va:) js:) de:> zu:) fl:( ss:| ls:[
    1. Om nah hoo pez nyeetz, Camping_RIDER!

      P.S.: An CK und Matthias Apsel - ihr seht an meinem Link oben, dass das Link-Parsen zumindest hier noch nicht immer ordentlich geht. Wahrscheinlich hätte ich die URI-encodete Variante nehmen müssen,

      Ja.

      dazu war ich aber zu faul. Und 0815-User weiß nicht wie das geht.

      Eigentlich sollten die Browser den Inhalt der Adresszeile gleich vernünftig anbieten.

      Oder hab ich was anderes falsch gemacht?

      Du hast nicht die Vorschau benutzt ;-p

      Matthias

      --
      Der Unterschied zwischen Java und JavaScript ist größer als der zwischen Span und Spange.

      1. Aloha ;)

        dazu war ich aber zu faul. Und 0815-User weiß nicht wie das geht.

        Eigentlich sollten die Browser den Inhalt der Adresszeile gleich vernünftig anbieten.

        Tja, Google Chrome unter Android tut das scheinbar nicht :D Und eine von Hand eingehackte Addresse auch nicht.

        Ach, hoppla... Du hast Browser geschrieben und ich hab mit Chrome für Android geantwortet... Das ist ja etwa so, als ob du nen Hengst willst und ich verkauf dir nen Wallach -.-

        Vielleicht sollte man da überlegen, ob das für Version 4 auch anders geht (so, dass das automatisch erkannt wird). Mobilnutzung wird zunehmen und so :D

        Oder hab ich was anderes falsch gemacht?

        Du hast nicht die Vorschau benutzt ;-p

        Doch, hab ich :D Sonst hätte ich euch den Kommentar ja nicht hinterlassen können :D Das war quasi ein beabsichtigter Bug. Sogesehen ein Feature meines Postings :D

        Grüße,

        RIDER

        --
        Camping_RIDER a.k.a. Riders Flame a.k.a. Janosch Zoller
        ch:? rl:| br:> n4:? ie:% mo:| va:) js:) de:> zu:) fl:( ss:| ls:[
        1. Om nah hoo pez nyeetz, Camping_RIDER!

          Vielleicht sollte man da überlegen, ob das für Version 4 auch anders geht (so, dass das automatisch erkannt wird). Mobilnutzung wird zunehmen und so :D

          http://www.meine-kochwoche.de/?template=template_michel

          absichtlich nicht verlinkt

          Matthias

          --
          Der Unterschied zwischen Java und JavaScript ist größer als der zwischen rot und Rottweiler.

  3. Hi there,

    Ich habe aber auch schon Beiträge gesehen, wo empfohlen wurde einen Integer zu nehmen und die
    Beträge in Cent umzurechnen.
    Macht das Sinn?

    Wie würdet ihr das machen?

    Ich rechne grundsätzlich immer mit Cent (und Integern) weil es die Situation am besten abbildet. Auch wenn Cent währungstechnisch eine Untereinheit sind sind sie rechnerisch gesehen die eigentliche Währung - jeder Eurobetrag lässt sich in Cent ausdrücken und andererseits sind die Cents auch die geringste "Quantisierungseinheit"...

    1. Om nah hoo pez nyeetz, Klawischnigg!

      und andererseits sind die Cents auch die geringste "Quantisierungseinheit"...

      Nicht an der Tankstelle ;-)

      Matthias

      --
      Der Unterschied zwischen Java und JavaScript ist größer als der zwischen Kohl und Kohle.

      1. Tach!

        und andererseits sind die Cents auch die geringste "Quantisierungseinheit"...
        Nicht an der Tankstelle ;-)

        Und auch nicht beim Umrechnen von Währungen (z.B. DM in Euro). Es gibt durchaus Finanzanwendungen, bei denen kleinere Beträge als Cent eine Rolle spielen. So ganz pauschal: "nimm immer Integer" ist ohne den Anwendungsfall zu kennen keine gute Empfehlung.

        dedlfix.

        1. Hi there,

          Und auch nicht beim Umrechnen von Währungen (z.B. DM in Euro). Es gibt durchaus Finanzanwendungen, bei denen kleinere Beträge als Cent eine Rolle spielen. So ganz pauschal: "nimm immer Integer" ist ohne den Anwendungsfall zu kennen keine gute Empfehlung.

          Es ging aber nicht um Finanzanwendungen sondern um Preise. Und von der skurilen Tankstellengeschichte einmal abgesehen sind Preise idR in Cent und nicht in Bruchteilen davon angeschrieben.
          Abgesehen davon muss man, wenn man das wirklich einmal benötigen sollte, als Programmierer ohnehin schon vorher tätig werden und aus den Bruchtteilen, so sie auftreten sollten, ohnehin wieder ganze Cent machen - denn was machst Du, wenn Du zB eine Schnittstelle zum online-Banking brauchst? Da kann man auch nur Cent überweisen und keine Bruchteile davon - also warum nicht gleich die Preise als Integer abspeichern?

          1. Hallo zusammen,

            vielen Dank an alle für die Informationen.
            Ich sehe, es gibt auch hier durchaus unterschiedliche Ansichten. :-)

            Es ging aber nicht um Finanzanwendungen sondern um Preise.

            Ja, in dem konkreten Fall sind es wirklich "normale" Preise wie es im Einzelhandel wie Supermarkt, Baumarkt usw. gibt. Also etwa 9,99 Euro, 235,00, 1500,00 etc.

            Jetzt mal angenommen man würde diese Preise als Integer speichern.
            Das bedeutet dann man muss jede Eingabe mal 100 nehmen bzw. bei Komma als Cent Trennzeichen das Komma entfernen? Bei Eingabe mit Tausender Trennpunkt wie 1.500,00 müsste man zudem noch den Punkt entfernen bzw. berücksichtigen. Wenn man dann hinterher die Preise für den Anwender "richtig" anzeigen will, müsste man wieder durch 100 teilen und das Komma als Trennzeichen wieder einfügen.

            Das wäre dann aber schon etwas mehr Aufwand, als wenn man es mit Decimal speichert oder?

            vielen Dank und viele Grüße
            hawk

            1. Tach!

              Das wäre dann aber schon etwas mehr Aufwand, als wenn man es mit Decimal speichert oder?

              Kommt drauf an. Den Aufwand der Normalisierung und der Formatierung/Lokalisierung hast du in jedem Fall. Wenn du mit PHP nicht rechnen willst, nimm normalisierte Strings für das Hin und Her im Programm (zuzüglich Eingabe- und Ausgabebehandlung) und im DBMS den Typ DECIMAL. Wenn du dann doch rechnen willst, musst du die Funktionen der Extensions GMP oder BCMath verwenden. Bei dieser Variante kannst du auch problemlos im DBMS rechnen (SUM() beispielsweise).

              Oder du willst viel in PHP rechnen, dann ist Integer vorteilhafter mit der Umrechnung bei Ein- und Ausgabe. Welches Format du dann im DBMS nimmst, INTEGER oder DECIMAL, das muss man dann auch noch mal individuell bewerten.

              dedlfix.

            2. Aloha ;)

              Jetzt mal angenommen man würde diese Preise als Integer speichern.
              Das bedeutet dann man muss jede Eingabe mal 100 nehmen bzw. bei Komma als Cent Trennzeichen das Komma entfernen? Bei Eingabe mit Tausender Trennpunkt wie 1.500,00 müsste man zudem noch den Punkt entfernen bzw. berücksichtigen. Wenn man dann hinterher die Preise für den Anwender "richtig" anzeigen will, müsste man wieder durch 100 teilen und das Komma als Trennzeichen wieder einfügen.

              Das wäre dann aber schon etwas mehr Aufwand, als wenn man es mit Decimal speichert oder?

              Du vermischst hier Ausgabe und Speicherung mit Verarbeitung. Bei der Erkennung von Nutzereingaben musst du vorsichtig sein, egal ob du die Beträge als Euro (decimal) oder als Cent (integer) speicherst. Der Nutzer gibt ja einen String ein, interpretieren, damit ne Zahl bei rumkommt, musst du das dann. Genauso musst du auch den String, der aus der Datenbank kommt (oder in welchem PHP-eigenen Format auch immer der aus der Datenbank kommt) zunächst wieder interpretieren. Aufwand hast du also so oder so.

              Imho sind Integer aus der Datenbank einfacher zu interpretieren, zumal du im Idealfall das Rechnen / die Verarbeitung nur mit Integern vornimmst. Dann musst du in deinem Quellcode nicht drauf achten und kannst gezielt immer nur dann, wenn der User damit in Berührung kommt (I/O), in float umwandeln (geteilt durch 100) und wieder zurück. Du hast dann genauere Klarheit, wo Integer und wo float ankommt. Wenn du decimal in der Datenbank gespeichert hast wird das beim Abrufen (zumindest in PHP) zu float und du hast Misch-Masch. Meine Meinung. Wenn du lieber mit float rechnest und die Probleme der Fließkommaarithmetik ignorieren willst, darfst du das natürlich auch gern machen.

              Interessant ist noch die Frage der Interpretation der Nutzereingaben. Weil man sowohl deutsche als auch englische Dezimaltrennung berücksichtigen muss.

              Beispiele für mögliche Nutzereingaben und ihre sinnvolle Entsprechung:

              1500.02    -> 1 500 02 ct
              1500,02    -> 1 500 02 ct
              1.500,02   -> 1 500 02 ct
              1,500,02   -> 1 500 02 ct
              1,500      -> 1 500 00 ct
              1.500      -> 1 500 00 ct
              1,50       ->     1 50 ct
              1.50       ->     1 50 ct
              1.5        ->     1 50 ct
              1,5        ->     1 50 ct

              Da ich immer noch nicht weiß, womit du serverseitig in der Verarbeitung arbeitest kriegst du den Algorithmus, den ich anwenden würde, in Prosa:

              1.: Suche letztes Vorkommen von "," oder "." im Input-String (am besten mit regulärem Ausdruck, dann kannst du gleich die Korrektheit des Eingabeformats sicherstellen. Also sowas wie 1.50,20 gleich wegen falscher 1000er Trennung als Fehleingabe identifizieren)
              2.: Falls kein Fund, Input-String um "00" erweitern, zu Integer umwandeln, fertig.
              3.: Falls Fund: Gefundenes letztes Trennzeichen muss entweder einziges verwendetes Trennzeichen sein oder darf nur einmal vorkommen
              4.: Falls einziges verwendetes Trennzeichen und exakt drei Stellen danach: Hänge "00" an Input-String an, entferne alle Nicht-Zahlen, zu Integer umwandeln, fertig
              5.: Falls nur einmal verwendet und maximal zwei Stellen, mindestens eine Stelle danach: Hänge je nachdem "0" oder nichts an, entferne Nicht-Zahlen, zu Integer umwandeln, fertig
              6.: Ansonsten: Fehleingabe.

              PHP und andere konkrete Fälle kennen dafür u.U. native Funktionen.

              Grüße,

              RIDER

              --
              Camping_RIDER a.k.a. Riders Flame a.k.a. Janosch Zoller
              ch:? rl:| br:> n4:? ie:% mo:| va:) js:) de:> zu:) fl:( ss:| ls:[
              1. Tach!

                Imho sind Integer aus der Datenbank einfacher zu interpretieren, zumal du im Idealfall das Rechnen / die Verarbeitung nur mit Integern vornimmst. Dann musst du in deinem Quellcode nicht drauf achten und kannst gezielt immer nur dann, wenn der User damit in Berührung kommt (I/O), in float umwandeln (geteilt durch 100) und wieder zurück.

                Na nee, das floaten wollen wir ja grad vermeiden. Der Rundungsfehler soll auch nicht kurz vorm Ziel auftreten. Lieber eine stringverarbeitende Funktion zum Formatieren des Integers schreiben.

                substr_replace(123456789, '.', -2, 0)

                Damit bekommt man einen Dezimalpunkt in die Zahl, ohne dass gerechnet und gerundet wird. Wenn man nun noch Tausender-Trenner braucht, wird es etwas aufwendiger. Ich wollte da noch number_format() draufsetzen, aber das konvertiert vermutlich nach Float, weil es sowas als Parameter haben möchte. Eigentlich wollte ich das mal testen, aber ich fand keine Zahl bis 7-stellig, bei der beim Teilen durch 100 ein Rundungsfehler auftritt. Unabhängig davon würde ich trotzdem Float aus dem Spiel raushalten.

                Wenn du decimal in der Datenbank gespeichert hast wird das beim Abrufen (zumindest in PHP) zu float und du hast Misch-Masch.

                Nein, DECIMAL- und FLOAT-Spalten-Werte kommen bei PDO und mysqli als String zurück.

                Interessant ist noch die Frage der Interpretation der Nutzereingaben. Weil man sowohl deutsche als auch englische Dezimaltrennung berücksichtigen muss.

                Das muss man dann definieren, je nach Anwendungsgebiet (im geografischen Sinne). Da eine Ratefunktion zu schreiben, halte ich nicht für sonderlich sinnvoll. Zu viel Aufwand für alle möglichen Fälle und fehlerfrei bekommt man das nicht. Dann lieber reginalabhängig (wie auch immer man das ermittelt oder festlegt) die Tausender und Dezimalzeichen abfragen (da gibts Datensammlungen, vor allem in den Frameworks) und das eine löschen, das andere zum Punkt normalisieren.

                dedlfix.

                1. Aloha ;)

                  Imho sind Integer aus der Datenbank einfacher zu interpretieren, zumal du im Idealfall das Rechnen / die Verarbeitung nur mit Integern vornimmst. Dann musst du in deinem Quellcode nicht drauf achten und kannst gezielt immer nur dann, wenn der User damit in Berührung kommt (I/O), in float umwandeln (geteilt durch 100) und wieder zurück.

                  Na nee, das floaten wollen wir ja grad vermeiden. Der Rundungsfehler soll auch nicht kurz vorm Ziel auftreten.

                  Das stimmt mMn so nicht ganz. Ein Rundungsfehler tritt an dieser Stelle (zumindest mathematisch begründbar) nicht auf. float-Werte werden nur für die Ausgabe (!) genutzt. Die Eingabe muss ja so oder so interpretiert werden. Außerdem ist die Eingabe immer exakt. Jetzt ist es also aufgrund meines Lösungsdesigns (Integer überall außer zur Ausgabe) so, dass mit float-Beteiligung nur folgende beide Operationen passieren:

                  float * 100    und     int / 100

                  Rundungsfehler, die du hier zitierst, treten in diesem Fall aber (zumindest mathematisch gesehen aufgrund der Gleitkommaarithmetik) überhaupt nicht auf. Wenn ich hier einen Rundungsfehler bekäme, dann nur deshalb, weil der gewählt Datentyp zu wenig Bits zur Verfügung hat, der Wert also nicht im Scope liegt. Nein, die Flinte mit der Ungenauigkeit liegt woanders im Korn. Nämlich sobald ich mit floats bestimmte problematische Operationen ausführe. Dazu zählen: Subtraktionen, Additionen, Vergleichsoperationen, Äquvialenzumformungen nach Assoziativ- und Distributivgesetz. Multiplikationen gehören insbesondere nicht dazu, solange keine Scope-bedingten Rundungsfehler auftreten. Außerdem sprechen wir bei diesen Ungenauigkeiten von Effekten, die sich erst nach mehrmaligen Operationen kumulieren und dadurch sichtbar werden. Das ist zumindest das, was mathematisch bei Fließkommaarithmetik passiert. Ob in diversen Programmiersprachen noch zusätzliche Problematiken aufgrund schlechter Implementierung auftreten, kann ich nicht beurteilen.

                  Aber das ist eventuell alles auf die Begründung bezogene Erbsenzählerei, denn...

                  Damit bekommt man einen Dezimalpunkt in die Zahl, ohne dass gerechnet und gerundet wird. Wenn man nun noch Tausender-Trenner braucht, wird es etwas aufwendiger. [...] Unabhängig davon würde ich trotzdem Float aus dem Spiel raushalten.

                  In diesem Fall stimme ich dir natürlich zu: Die von dir genannte Methode ist sicher die Bessere. IMHO hast du insgesamt Recht, nur die Begründung oben war mMn (zumindest so wie ich sie verstanden hatte) nicht die richtige.

                  Wenn du decimal in der Datenbank gespeichert hast wird das beim Abrufen (zumindest in PHP) zu float und du hast Misch-Masch.

                  Nein, DECIMAL- und FLOAT-Spalten-Werte kommen bei PDO und mysqli als String zurück.

                  Ja, schon. Und wenn ich dann damit rechnen möchte tu ich was? Dann habe ich wieder nur die zwei Möglichkeiten, es als float oder integer zu Interpretieren, um die Werte weiterverarbeiten zu können (denn mit Strings rechnet es sich schwerlich). Daher mein flapsiges "wird das beim Abrufen zu float". Denn wenn ich es nach dem Abrufen direkt als Integer interpretiere hätte ich es doch auch direkt als Integer speichern können.

                  Interessant ist noch die Frage der Interpretation der Nutzereingaben. Weil man sowohl deutsche als auch englische Dezimaltrennung berücksichtigen muss.

                  Das muss man dann definieren, je nach Anwendungsgebiet (im geografischen Sinne). Da eine Ratefunktion zu schreiben, halte ich nicht für sonderlich sinnvoll. Zu viel Aufwand für alle möglichen Fälle und fehlerfrei bekommt man das nicht. Dann lieber reginalabhängig (wie auch immer man das ermittelt oder festlegt) die Tausender und Dezimalzeichen abfragen (da gibts Datensammlungen, vor allem in den Frameworks) und das eine löschen, das andere zum Punkt normalisieren.

                  Findest du? Ich weiß nicht, aber ich bin ziemlich sicher, dass meine oben gepostete Ratefunktion exakt arbeitet. Ich bin da eher Freund von Toleranz, was das Akzeptieren von Nutzereingaben angeht (natürlich nur, solange es soweit als möglich eindeutig interpretierbar bleibt). Die User werden von gängigen Programmen schon oft genug hin und her geworfen (manche akzeptieren deutsche Schreibweise, manche nicht - wissen tut mans oft erst, wenn das Programm den ersten Fehler spuckt). Ich fand im Gegenteil meine Überprüfung eigentlich ziemlich vollständig. Zumindest alle von mir geposteten Beispiele lassen sich damit sinnvoll interpretieren und mir mag kein Gegenbeispiel einfallen.

                  Natürlich könnte der User statt 140,00 meinen: 140,000 -> 140 000 00 ct und nicht 140 00 ct. Dieses Problem (vergessene Stellen) ist aber nie verhinderbar - er könnte ja genauso gut schreiben 140 00 statt: 140 000 und niemandem würde es auffallen. Das ist also imho verschmerzbarer, als dem User eine Schreibweise aufzudrücken, wenn es auch anders geht.

                  Grüße,

                  RIDER

                  --
                  Camping_RIDER a.k.a. Riders Flame a.k.a. Janosch Zoller
                  ch:? rl:| br:> n4:? ie:% mo:| va:) js:) de:> zu:) fl:( ss:| ls:[
            3. Mahlzeit,

              Ja, in dem konkreten Fall sind es wirklich "normale" Preise wie es im Einzelhandel wie Supermarkt, Baumarkt usw. gibt. Also etwa 9,99 Euro, 235,00, 1500,00 etc.

              Macht es wirklich Sinn, wenn du Brutto-Preise speicherst? Wenn sich irgendwann mal die MwSt. ändert, stimmen alle deine Preise nicht mehr. Deshalb speichert man auch im Einzelhandel sowas grundsätzlich Netto.

              Und dann kannst du das mit Centbeträgen knicken, weil du Rundungsfehler bekommst.

              Das wäre dann aber schon etwas mehr Aufwand, als wenn man es mit Decimal speichert oder?

              Nicht wirklich. Du kannst ja die Integer intern nutzen aber bei der Ausgabe formatieren.

              --
              eigentlich ist mir bewusst, dass ich hin und wieder einfach mal die Klappe halten sollte. Doch genau in den unpassendsten Momenten erwische ich mich dabei, wie ich dennoch etwas sage ...
      2. Hi there,

        und andererseits sind die Cents auch die geringste "Quantisierungseinheit"...

        Nicht an der Tankstelle ;-)

        Naja, dann kauf einmal einen Liter Super und lass' Dir genau herausgeben...;)

        Dedlfix  hat nicht ganz unrecht, wenn er meint, den Anwendungsfall bedenken zu müssen, aber idR ist Währung, womit bezahlt wird, und mit Teilen von Cents kann man eben nicht bezahlen, und deshalb meine ich, daß Währung in Datenbanken durch Integer besser repräsentiert wird als durch andere Zahlenformate.
        Wenn Dedlfix zB das Umrechnen von Währungen erwähnt, dann geht es um das  Speichern von Währungs*kursen*, nicht der Währung selbst, das ist aber etwas anderes als das vom OP Hinterfragte...

        1. Mahlzeit,

          Naja, dann kauf einmal einen Liter Super und lass' Dir genau herausgeben...;)

          Deshalb muss vorher auch mit den zehnteln gerechnet werden. Oder willst du bei jedem Liter, dass der Preis aufgerundet werden kann?
          Gleiches gilt für Umrechnugen von MwSt. etc. Wenn du da nur mit Cent rechnest, bekommst du Rundungsfehler, dass dir schwindelig wird.
          Übliche Kassensysteme rechnen auch im Einzelhandel mit 7-14 Stellen hinter dem Komma.

          BTW: Im Grosshandel sind bei Kleinpreis-Artikeln Preise im hunderstel-Bereich durchaus üblich, also Cent mit zwei Kommastellen.

          Also ist es ziemlich kurzsichtig, nur mit Cent zu rechnen.

          Was mir noch als Beispiel einfällt, ist die Umrechnung in andere Währungen, wer da nur mit Cent rechnet bescheisst entweder den Kunden oder sich selbst.

          --
          eigentlich ist mir bewusst, dass ich hin und wieder einfach mal die Klappe halten sollte. Doch genau in den unpassendsten Momenten erwische ich mich dabei, wie ich dennoch etwas sage ...
          1. Hi there,

            Mahlzeit,

            Naja, dann kauf einmal einen Liter Super und lass' Dir genau herausgeben...;)

            Deshalb muss vorher auch mit den zehnteln gerechnet werden. Oder willst du bei jedem Liter, dass der Preis aufgerundet werden kann?
            Gleiches gilt für Umrechnugen von MwSt. etc. Wenn du da nur mit Cent rechnest, bekommst du Rundungsfehler, dass dir schwindelig wird.

            Es geht aber nicht ums Rechnen sondern um das Abspeichern und das Repräsentieren von Preisen in einer Datenbanktabelle.

            Was mir noch als Beispiel einfällt, ist die Umrechnung in andere Währungen, wer da nur mit Cent rechnet bescheisst entweder den Kunden oder sich selbst.

            siehe oben...

            1. Mahlzeit,

              Es geht aber nicht ums Rechnen sondern um das Abspeichern und das Repräsentieren von Preisen in einer Datenbanktabelle.

              Wenn es einzig darum geht und nie um was andere gehen wird, ist es eh kaum relevant, wie gespeichert wird, dann kannste auch als varchar speichern.
              Allerdings stellt sich mir da eher die Frage, ob eine Datenbank generell nötig ist. Bei einem grossen Projekt dürfte es keinen Anlass geben irgendwelche Preise nur zu speichern, bei kleinen Projekte dürfte ein DBMS überdimensioniert sein.

              --
              eigentlich ist mir bewusst, dass ich hin und wieder einfach mal die Klappe halten sollte. Doch genau in den unpassendsten Momenten erwische ich mich dabei, wie ich dennoch etwas sage ...