Franz Josef: mySQL varchar() ignoriert Null

Hallo,

ich habe folgendes [sehr merkwürdiges] Problem...

Gegeben sind eine Zahl, die automatisch generiert und in einer Datenbank gespeichert wird. Das funktioniert soweit auch - nur '0123' wird in der Datenbank zu '123' umgewandelt.

Die Datenbankspalte, in der die Werte gespeichert werden ist vom Typ aber an und für sich varchar(11)!

-- Trotzdem werden vorangestellte Nullen gelöscht.

Wenn ich die Variablen in der PHP-Datei auslesen lasse, also quasi 'echo $variable;', so wird die vorangestellte Null sehr wohl angezeigt, also muss es sich wohl um ein Datenbankproblem handeln...

[NACHTRAG] So oft ich die Struktur der Datenbank auch neu lade, die Spalte ist vom Typ her varchar()! Ich starre gerade etwas entgeistert auf meinen Bildschirm ... ...ERM ... Hilfe? [/NACHTRAG]

P.S.: UNSIGNED ZEROFILL ist nicht wirklich eine Option - ich will, dass die Datenbank die Nullen speichert, die ihr auch effektiv zugewiesen werden.

akzeptierte Antworten

  1. Hi,

    Gegeben sind eine Zahl, die automatisch generiert und in einer Datenbank gespeichert wird. Das funktioniert soweit auch - nur '0123' wird in der Datenbank zu '123' umgewandelt.

    das würde ich bei einem sinnvollen Datenmodell erwarten (eventuell sogar, dass 0123 zu 83 wird).

    Die Datenbankspalte, in der die Werte gespeichert werden ist vom Typ aber an und für sich varchar(11)!

    Warum? Warum nicht NUMBER oder DECIMAL? Die Formatierung z.B. mit führenden Nullen sollte bei der Ausgabe erfolgen, nicht Teil der gespeicherten Daten sein. Oder handelt es sich gar nicht um eine Zahl, sondern eher eine Art Kennung, etwa eine Artikelnummer oder so?

    Wenn ich die Variablen in der PHP-Datei auslesen lasse, also quasi 'echo $variable;', so wird die vorangestellte Null sehr wohl angezeigt, also muss es sich wohl um ein Datenbankproblem handeln...

    Dann lass dir mal das SQL-Statement anzeigen. Eventuell hilft das weiter.

    So long,
     Martin

    --
    Nothing travels faster than the speed of light with the possible exception of bad news, which obeys its own special laws.
    - Douglas Adams, The Hitchhiker's Guide To The Galaxy
    1. Ich gehe mal davon aus, dass Du den Wert der Variablen direkt ins SQL Statement gehämmert hast und dabei keine Anführungszeichen verwendet hast. Dann ist das Verhalten von MySQL absolut korrekt.

      1. Hallo - noch während du die [natürlich korrekte] Fehleranalyse hier gepostet hast, bin ich genau diesem Bug auf die Schliche gekommen - und mit INSERT INTO tabelle (spalte) VALUES ('$wert') statt INSERT INTO tabelle (spalte) VALUES ($wert) funktioniert es jetzt auch! Vielen Dank trotzdem!

        LG, FJ

        1. Hallo und guten Morgen,

          noch während du die [natürlich korrekte] Fehleranalyse hier gepostet hast, bin ich genau diesem Bug auf die Schliche gekommen - und mit INSERT INTO tabelle (spalte) VALUES ('$wert') statt INSERT INTO tabelle (spalte) VALUES ($wert) funktioniert es jetzt auch! Vielen Dank trotzdem!

          Und nun solltest Du die Werte im SQL-Statement noch richtig escapen, dann solltest Du auch vor SQL-Injections geschützt sein!

          Grüße
          TS

          --
          es wachse der Freifunk
          http://freifunk-oberharz.de
  2. Hallo

    ich habe folgendes [sehr merkwürdiges] Problem...

    Gegeben sind eine Zahl, die automatisch generiert und in einer Datenbank gespeichert wird. Das funktioniert soweit auch - nur '0123' wird in der Datenbank zu '123' umgewandelt.

    Die Datenbankspalte, in der die Werte gespeichert werden ist vom Typ aber an und für sich varchar(11)!

    Wie sieht der Wert auf dem Weg in die Datenbank aus? kann es sein, dass er durch die automatische Typkonvertierung von PHP vorübergehend und genau bei der Ankunft in der DB eine Zahl ist?

    Wie sieht denn die Abfrage selbst aus?

    Tschö, Auge

    --
    Wo wir Mängel selbst aufdecken, kann sich kein Gegner einnisten.
    Wolfgang Schneidewind *prust*
  3. P.S.: Da ich dieses Thema nun mal schon angerissen habe, vielleicht noch eine kleine Verständnisfrage: Wenn ich einen Wert als INT() in meiner Datenbank speichere, ist es dann von Relevanz, ob ich die Zahlenwerte mit Anführungszeichen eintrage oder nicht?

    Sprich:

    Funktionieren sowohl

    INSERT INTO tabelle (spalte) VALUES (1234)

    als auch

    INSERT INTO tabelle (spalte) VALUES ('1234')

    ?

    Danke und liebe Grüße, FJ

    1. INSERT INTO tabelle (spalte) VALUES (1234)

      als auch

      INSERT INTO tabelle (spalte) VALUES ('1234')

      Der erste Fall sollte einen Fehler ergeben, denn du meintest, das Feld sei varchar. Da sind Gänse- oder andere Füße um den Wert Pflicht.

      Aber das ist nicht dein ursprüngliches Problem, weil ohne führende 0 (Ziffer 0, der Begriff NULL ist was anderes).

      1. Hallo,

        denn du meintest, das Feld sei varchar.

        ich habe ihn so verstanden, dass er jetzt den Fall meint, ein als INT deklariertes Feld zu haben. Ich geh davon aus, dass beide Fälle ohne Fehler akzeptiert werden, nur beim zweiten wundert man sich über lauter Nullwerte...

        Gruß
        Kalk

        1. ich habe ihn so verstanden, dass er jetzt den Fall meint, ein als INT deklariertes Feld zu haben. Ich geh davon aus, dass beide Fälle ohne Fehler akzeptiert werden, nur beim zweiten wundert man sich über lauter Nullwerte...

          Alles klar, Danke!

    2. Tach!

      Wenn ich einen Wert als INT() in meiner Datenbank speichere, ist es dann von Relevanz, ob ich die Zahlenwerte mit Anführungszeichen eintrage oder nicht?

      Vor dem Eintragen in die Tabelle ist da ja erstmal das Statement. Und das ist eine Aneinanderreihung von Zeichen, die vom Statement-Parser erstmal interpretiert werden muss. Gegebenenfalls muss auch ein Ausdruck berechnet werden. Dann muss geschaut werden, welchem Typ das Feld angehört und der Wert muss in die interne binäre Darstellung dieses Typs gebracht werden.

      Was ich sagen will: du bist nicht derjenige, der die Werte einträgt, du bist nur derjenige, der ein syntaktisch gültiges Statement als String erstellt. Darin befinden sich die Werte in Form diverser Literale. Ein Literal ist die Darstellung eines bestimmten Wertes mithilfe von Zeichen, gegebenenfalls mit zusätzlichen Begrenzungs- und Maskierungszeichen.

      Die Regeln des DBMS legen auch fest, welche Umwandlungen stattfinden, wenn zwei Werte eines bestimmten Typs in einem Ausdruck miteinander berechnet werden, und sei es auch nur eine Zuweisung eines Wertes an eine Variable oder ein Feld eines anderen Typs.

      Sprich:

      Funktionieren sowohl

      INSERT INTO tabelle (spalte) VALUES (1234)

      als auch

      INSERT INTO tabelle (spalte) VALUES ('1234')

      ?

      Ja, im ersten Fall gibt es kein Problem, das Integer-Literal wird als Integer interpretiert. Im zweiten Fall trifft nun ein String-Literal auf einen Integer-Typ, und da versucht das MySQL die im String enthaltenen Zeichen soweit wie möglich als Zahl zu interpretieren (Integer, Kommazahl, Exponentialdarstellung). Der Rest der Zeichenfolge wird ab dem ersten der für Zahlen ungültigen Zeichen ignoriert.

      Die Alternative zum Einfügen von Werten als Literal in Statements hört übrigens auf den Namen Prepared Statement. Da musst du dir die Frage nach dem Begrenzungszeichen prinzipbedingt gar nicht mehr stellen. Auch Gedanken zur Beachtung des Kontextwechsel und der dafür notwendigen Maskierregeln entfallen. Es ist aber weiterhin möglich, eine Zahl als Stringliteral zu übergeben, wenn eigentlich ein Zahlentyp erwartet wird. Das wird dann den Regeln entsprechend konvertiert.

      dedlfix.