Moni: Deustche, Kommazahl in Datenbanbk schreiben

Ich habe ein Problem, und zwar habe ich eine String Variable in er eine deutsche Kommazahl steht. 4,8 und wenn ich diese versuche in meine mysql Datenbankzu schreiben geht das nicht. Gibt es eine einfache möglichkeit das KOMMA durch einen PUNKT zu ersetzen?

Moni

  1. Hallo

    Ich habe ein Problem, und zwar habe ich eine String Variable in er eine deutsche Kommazahl steht. 4,8 und wenn ich diese versuche in meine mysql Datenbankzu schreiben geht das nicht.

    „Geht nicht gibt's nicht.“, wie mein Lehrmeister zu sagen pflegte.

    Da wir deinen Code nicht kennen, können wir nicht sagen, warum es nicht funktioniert. Deshalb stattdessen ein Frage.

    Du sagst, dass die „Kommazahl“ ein String ist. Welchen Datentyp hat das Feld der Datenbanktabelle, in das du diesen Wert einfügen willst?

    Tschö, Auge

    --
    Wir hören immer wieder, dass Regierungscomputer gehackt wurden. Ich denke, man sollte die Sicherheit seiner Daten nicht Regierungen anvertrauen.
    Jan Koum, Mitgründer von WhatsApp, im Heise.de-Interview
  2. Hallo Moni,

    Ich habe ein Problem, und zwar habe ich eine String Variable in er eine deutsche Kommazahl steht. 4,8 und wenn ich diese versuche in meine mysql Datenbankzu schreiben geht das nicht. Gibt es eine einfache möglichkeit das KOMMA durch einen PUNKT zu ersetzen?

    Das geht schon (indem du die Spalte als CHARACTER VARYING oder so anlegst), das solltest du aber nicht tun. Das Ersetzen des Punkts durch ein Komma ist eine Frage der Darstellung, Zahlen versteht die Datenbank üblicherweise nur mit Punkt als Dezimaltrennzeichen. Bei der Ausgabe wandelst du dann die Zahl via z.B. number_format (PHP) oder number_with_precisition (Rails), … um.

    LG,
    CK

  3. Moin!

    in meine mysql Datenbank ...
    Gibt es eine einfache möglichkeit das KOMMA durch einen PUNKT zu ersetzen?

    Einfach? Einfach!

    INSERTVALUES(, REPLACE('4,8', ',', '.'),)
    

    mysql:stringfunktionen#replace

    Allerdings könnte es gut sein, dass eine weitere Validierung der Eingabe notwendig wird. Was, wenn der Benutzer '1.004,8' eingab?

    Welche Programmiersprache wird denn benutzt und wo kommen die Eingaben her?

    Jörg Reinholz

    1. Moin!

      Hier ein Skript (die Funktion) zum Spekulieren über die Zahleneingaben.

      Es zeigt im 2. Test auch die Grenzen deutlich auf.

      <?php
      
      function speculateAboutTheNumber($str, $guess='decimal', $type='dec') {
          ## Arguments:
          # $str :: The input
          # $guess :: 'decimal' (Guess the comma or point separate the decimal part) (100,123 or 100.123 -> 100.123) [ =default ]
          # $guess :: 'thousends'  (Guess the comma or point separate thousends) (100,123 or 100.123 -> 100123)
          # $guess :: false  - Guess nothing, return false (100,123 and 100,123 -> false)
      
          # $type :: 'dec' or decimal - for decimal values (float) [ =default ]
          # $type :: 'int' or integer - for integers
      
          $type = substr(strtolower($type), 0, 3);
          if ($type == 'flo') $type='dec';
          if ($type != 'dec' && $type != 'int') {
              if (! defined('__FILE__') ) define ('__FILE__', 'cli:');
              error_log(__FILE__ . ' : Aufruf speculateAboutTheNumber("' . $str . '", "' . $guess . '", "' . $type . '") : $type muss dec oder int sein');
              return false;
          }
          if ($guess !==false && $guess != 'decimal' && $guess != 'thousends') {
              if (! defined('__FILE__') ) define ('__FILE__', 'cli:');
              error_log(__FILE__ . ' : Aufruf speculateAboutTheNumber("' . $str .'", "'. $guess . '", "' . $type . '") : $guess muss false, decimal oder thousends sein');
              return false;
          }
      
          $str=trim($str);
      
          # french peoples love to separate tousends by a space, others by a single-quota
          $str=str_replace(array(' ', '\''), '', $str);
      
          # a simple integer
          if ( 1 === preg_match('/^-{0,1}\d*$/', $str) ) {
              return intval($str);
          }
      
          $posPoint = strpos($str, '.');
          $posComma = strpos($str, ',');
      
      
          if (false === $posPoint) {
              if (1 == preg_match('/^-{0,1}\d{1,3},\d{3}$/', $str) ) {
                  if (false===$guess) {
                      error_log(__FILE__ . ' : Aufruf speculateAboutTheNumber("'.$str.'", false, "'.$type.'")  decimal-point or thousender-separator? Nobody knows!');
                      return false;
                  } elseif ('thousends'===$guess) {
                      $str=str_replace(',', '', $str);
                  }
              }
          }
          if (false === $posComma) {
              if (1 == preg_match('/^-{0,1}\d{1,3}\.\d{3}$/', $str) ) {
                  if (false===$guess) {
                      error_log(__FILE__ . ' : Aufruf speculateAboutTheNumber("'.$str.'", false, "'.$type.'")  decimal-point or thousender-separator? Nobody knows!');
                      return false;
                  } elseif ('thousends'===$guess) {
                      $str=str_replace('.', '', $str);
                  }
              }
          }
      
          # a simple decimal with a point
          if ( 1 == preg_match('/^-{0,1}\d*\.\d+$/', $str) ) {
              if ($type == 'dec') {
                  return floatval($str);
              } else {
                  return intval($str);
              }
          }
      
          # a simple decimal with a comma (german format)
          if ( 1 == preg_match('/^-{0,1}\d*,\d+$/', $str) ) {
              $str = str_replace(',', '.', $str);
              if ($type == 'dec') {
                  return floatval($str);
              } else {
                  return intval($str);
              }
          }
      
          # a simple decimal with a point (international format)
          if ( 1 == preg_match('/^-{0,1}\d*\.\d+$/', $str) ) {
              if ($type == 'dec') {
                  return floatval($str);
              } else {
                  return intval($str);
              }
          }
      
          if ( $posPoint ) {
              if ($posComma < $posPoint) {
                  $str = str_replace(',', '', $str);
              }
      
          }
          if ( $posComma ) {
              if ($posPoint < $posComma) {
                  $str = str_replace('.', '', $str);
                  $str = str_replace(',', '.', $str);
              }
          }
          if ($type == 'dec') {
              return floatval($str);
          } else {
              return intval($str);
          }
      }
      
      
      ## Tests
      #/*
      
      $ar=explode(';', "4.8; 4,8; .8; ,8; 1.004,8; 1,004.8; 1 004.8; 1 004,8; -1 004.8");
      
      foreach ($ar as $str) {
          echo trim($str), "\t", speculateAboutTheNumber($str, false, 'int'), "\t", speculateAboutTheNumber($str, false, 'dec'), "\n";
      }
      
      echo "-----------------2. Test -------------------------\n";
      $ar=explode(';', "2.004; -2,004");
      foreach ($ar as $str) {
          echo trim($str), "\t", speculateAboutTheNumber($str, 'decimal', 'dec'), "\t", speculateAboutTheNumber($str, 'thousends', 'dec'), "\t", speculateAboutTheNumber($str, false, 'dec'), "\n";
      }
      
      #*/
      

      Jörg Reinholz

      1. Moin!

        An solchen Geschichten gibt es immer was zu meckern und ergo immer was zu verbessern:

        <?php
        
        function speculateAboutTheNumber($str, $guess='decimal', $type='dec') {
            ## Arguments:
            # $str :: The input
            # $guess :: 'decimal' (Guess the comma or point separate the decimal part) (100,123 or 100.123 -> 100.123) # default
            # $guess :: 'thousends'  (Guess the comma or point separate thousends) (100,123 or 100.123 -> 100123)
            # $guess :: false  - Guess nothing, return false (100,123 and 100,123 -> false)
        
            # $type :: 'dec' or decimal - for decimal values (float) [ =default ]
            # $type :: 'int' or integer - for integers
        
            $type = substr(strtolower($type), 0, 3);
            if ($type == 'flo') $type='dec';
            if ($type != 'dec' && $type != 'int') {
                if (! defined('__FILE__') ) define ('__FILE__', 'cli:');
                error_log(__FILE__ . ' : Aufruf speculateAboutTheNumber("' . $str . '", "' . $guess . '", "' . $type . '") : $type muss dec oder int sein');
                return false;
            }
            if ($guess !==false && $guess != 'decimal' && $guess != 'thousends') {
                if (! defined('__FILE__') )     if ( 1 < substr_count($str, ',') ) $str=str_replace(',', '', $str);
            if ( 1 < substr_count($str, '.') ) $str=str_replace('.', '', $str);define ('__FILE__', 'cli:');
                error_log(__FILE__ . ' : Aufruf speculateAboutTheNumber("' . $str .'", "'. $guess . '", "' . $type . '") : $guess muss false, decimal oder thousends sein');
                return false;
            }
        
            $str=trim($str);
        
            # french peoples love to separate tousends by a space, others by a single-quota
            $str=str_replace(array(' ', '\''), '', $str);
        
            # only the thousend-seps can count > 1
            if ( 1 < substr_count($str, ',') ) $str=str_replace(',', '', $str);
            if ( 1 < substr_count($str, '.') ) $str=str_replace('.', '', $str);
        
        
            # a simple integer
            if ( 1 === preg_match('/^-{0,1}\d*$/', $str) ) {
                return intval($str);
            }
        
            $posPoint = strpos($str, '.');
            $posComma = strpos($str, ',');
        
            if (false === $posPoint) {
                if (1 == preg_match('/^-{0,1}\d{1,3},\d{3}$/', $str) ) {
                    if (false===$guess) {
                        error_log(__FILE__ . ' : Aufruf speculateAboutTheNumber("'.$str.'", false, "'.$type.'")  decimal-point or thousender-separator? Nobody knows!');
                        return false;
                    } elseif ('thousends'===$guess) {
                        $str=str_replace(',', '', $str);
                    }
                }
            }
            
            if (false === $posComma) {
                if (1 == preg_match('/^-{0,1}\d{1,3}\.\d{3}$/', $str) ) {
                    if (false===$guess) {
                        error_log(__FILE__ . ' : Aufruf speculateAboutTheNumber("'.$str.'", false, "'.$type.'")  decimal-point or thousender-separator? Nobody knows!');
                        return false;
                    } elseif ('thousends'===$guess) {
                        $str=str_replace('.', '', $str);
                    }
                }
            }
        
        
            # a simple decimal with a point
            if ( 1 == preg_match('/^-{0,1}\d*\.\d+$/', $str) ) {
                if ($type == 'dec') {
                    return floatval($str);
                } else {
                    return intval($str);
                }
            }
        
            # a simple decimal with a comma (german format)
            if ( 1 == preg_match('/^-{0,1}\d*,\d+$/', $str) ) {
                $str = str_replace(',', '.', $str);
                if ($type == 'dec') {
                    return floatval($str);
                } else {
                    return intval($str);
                }
            }
        
        
            if ( $posPoint ) {
                if ($posComma < $posPoint) {
                    $str = str_replace(',', '', $str);
                }
        
            }
            if ( $posComma ) {
                if ($posPoint < $posComma) {
                    $str = str_replace('.', '', $str);
                    $str = str_replace(',', '.', $str);
                }
            }
            if ($type == 'dec') {
                return floatval($str);
            } else {
                return intval($str);
            }
        }
        
        
        ## Tests
        #/*
        
        $ar=explode(';', "4.8; 4,8; .8; ,8; 1.004,8; 1,004.8; 1 004.8; 1 004,8; -1 004.8; 101.102.103,104; 101,102,103.104");
        
        foreach ($ar as $str) {
            echo trim($str), "\t", speculateAboutTheNumber($str, false, 'int'), "\t", speculateAboutTheNumber($str, false, 'dec'), "\n";
        }
        
        echo "------------------------------------------\n";
        $ar=explode(';', "2.004; -2,004; 101.102.103; 101,102,103");
        foreach ($ar as $str) {
            echo trim($str), "\t", speculateAboutTheNumber($str, 'decimal', 'dec'), "\t", speculateAboutTheNumber($str, 'thousends', 'dec'), "\t", speculateAboutTheNumber($str, false, 'dec'), "\n";
        }
        
        #*/
        

        Jörg Reinholz