2012-07-23 5 views
30

Von meinem Tisch Skript erstellen, habe ich das hasMultipleColors Feld als BIT definiert:MySQL immer wiederkehr BIT Werte als leere

hasMultipleColors BIT NOT NULL, 

Wenn eine INSERT ausgeführt wird, gibt es keine Warnungen für diese geworfen oder die anderen BIT Felder, aber die Auswahl der Zeilen zeigt, dass alle BIT-Werte leer sind.

Manuell versuchen, diese Datensätze von der Befehlszeile aktualisieren gibt ungerade Wirkung - zeigt, dass der Datensatz übereinstimmte und geändert wurde (falls zutreffend), aber immer noch leer zeigt.

Server-Version: 5.5.24-0ubuntu0.12.04.1 (Ubuntu)

mysql> update pumps set hasMultipleColors = 1 where id = 1; 
Query OK, 0 rows affected (0.00 sec) 
Rows matched: 1 Changed: 0 Warnings: 0 

mysql> select hasMultipleColors from pumps where id = 1; 
+-------------------+ 
| hasMultipleColors | 
+-------------------+ 
|     | 
+-------------------+ 
1 row in set (0.00 sec) 

mysql> update pumps set hasMultipleColors = b'0' where id = 1; 
Query OK, 1 row affected (0.00 sec) 
Rows matched: 1 Changed: 1 Warnings: 0 

mysql> select hasMultipleColors from pumps where id = 1; 
+-------------------+ 
| hasMultipleColors | 
+-------------------+ 
|     | 
+-------------------+ 
1 row in set (0.00 sec) 

Irgendwelche Gedanken?

+1

Warum verwenden Sie nicht 'BOOL' statt' BIT' dafür? Aus der Semantik deines Feldnamens würde es mehr Sinn ergeben. – Romain

+2

Habe etwas über die Datentypen BOOL vs. BIT vs. TINYINT gelesen, und der Take-away war, dass MySQL BOOL sehr schlecht behandelt - nicht portierbar für andere RDBMS-Lösungen - daher ist es im Allgemeinen ideal, mit TINYINT zu arbeiten oder BIT (effizienter). – CdrXndr

Antwort

44

Sie müssen die Bit-Feld auf eine ganze Zahl werfen.

mysql> select hasMultipleColors+0 from pumps where id = 1; 

Dies aufgrund eines Fehlers ist, finden Sie unter: http://bugs.mysql.com/bug.php?id=43670. Der Status sagt: Wird nicht behoben.

+1

Verstanden, danke. Dies ist also nur ein Problem der Anzeige, anstatt dass die Daten ordnungsgemäß erfasst und gespeichert werden.Eine Möglichkeit zum automatischen Umwandeln von Bit-Datentypen bei Verwendung eines * in select? – CdrXndr

+1

Ich habe eine sehr seltsame Version von dieser, wo im ersten Fall die BIT-Felder ohne Problem anzeigen. Aber dann in einer anderen Tabelle, wo die BIT-Felder genau wie in der ersten Tabelle definiert sind, wird nichts gedruckt, es sei denn, ich mache etwas wie das Hinzufügen von 0 zu jeder BIT-Spalte. Wenn das ein Fehler ist, warum funktioniert es dann nur im ersten Fall, aber nicht im zweiten? TL: DR, um die blutigen Details zu geben. Eine andere Seltsamkeit: Während dieses Problem im mysql-Client auf meinem Server auftritt, hat der in meine IDE (PHPStorm) eingebaute Client das Problem überhaupt nicht und funktioniert nur mit BIT-Feldern. –

+0

@RTB gibt es eine einfache Lösung für dieses Problem, und ich habe es hinzugefügt. –

0

Der eigentliche Grund für den Effekt, den Sie sehen, ist, dass es richtig und wie erwartet gemacht wird.

Das Feld bit hat Bits und somit Rückgabebits. Wenn Sie versuchen, ein einzelnes Bit als Zeichen auszugeben, wird das Zeichen mit dem angegebenen Bitwert angezeigt - in diesem Fall ein Steuerzeichen mit der Breite Null.

Einige Software kann dies automatisch behandeln, aber für Befehlszeile MySQL müssen Sie es als Int in irgendeiner Weise (z. B. durch Hinzufügen von Null) zu werfen. In Sprachen wie PHP gibt Ihnen der Ordinalwert des Zeichens den richtigen Wert, indem Sie die ord() Funktion verwenden (obwohl sie wirklich richtig wäre, müsste sie von dezimalen in binäre Zeichenfolgen konvertiert werden, um länger für Bitfelder zu arbeiten) als ein Zeichen).

EDIT:
Fand eine ganz alte Quelle sagte, dass es geändert wird, so dass ein MySQL-Upgrade kann alles mehr funktioniert wie erwartet: http://gphemsley.wordpress.com/2010/02/08/php-mysql-and-the-bit-field-type/

2

Sie können unsigned werfen BIT-Feld.

SELECT CAST(hasMultipleColors AS UNSIGNED) AS hasMultipleColors from pumps where id = 1 

Es wird auf den Wert von hasMultipleColors 1 oder 0 basierend zurückzukehren.