Mysql
 sql >> Base de données >  >> RDS >> Mysql

MySQL 5.5 perd des espaces de fin dans la requête

Ce comportement est inhérent à la conception, pas seulement dans MySQL.

Vous pouvez contourner ce problème dans les comparaisons en utilisant BINARY :

mysql> select version(), 'a' = 'a ', BINARY 'a' = BINARY 'a ';
+-------------+------------+--------------------------+
| version()   | 'a' = 'a ' | BINARY 'a' = BINARY 'a ' |
+-------------+------------+--------------------------+
| 5.5.25a-log |          1 |                        0 |
+-------------+------------+--------------------------+
1 row in set (0.00 sec)

mais pas beaucoup plus. Cela vous aidera avec SELECT s si des espaces apparaissent par ex. dans l'entrée de l'utilisateur pour une recherche ; mais si vous voulez réellement entrer des informations suivies d'un espace blanc, ce sera un problème (vous ne pouvez pas avoir un index avec à la fois 'a' et 'a ').

Voir aussi

L'espace blanc de fin dans varchar a besoin à considérer en comparaison

Vous pourriez éventuellement inverser les chaînes de cette colonne et les inverser lors de leur affichage. Bien sûr, cela détruira tout ordre basé sur cette colonne, mais si vous ne testez que l'égalité ou l'existence d'une sous-chaîne, cela pourrait fonctionner. En tête les espaces comptent.

Pour les recherches d'égalité, vous pouvez également stocker l'encodage base64 de la chaîne, qui doit conserver l'ordre lexicographique (c'est-à-dire que l'ordre entre a et b doit être conservé entre base64(a) et base64(b)). Ou vous pouvez ajouter un terminateur à la chaîne ("\n" pourrait bien fonctionner et ne pas apparaître dans les recherches).

Enfin, mais c'est risqué car les humains ne peuvent pas faire la différence, vous pouvez remplacer les espaces par le char UTF8 (49824):

mysql> select concat ('\'a', char(49824),'\'') AS tricked,
              concat ('\'a', ' '        ,'\'') as honest,
              concat ('\'a', char(49824),'\'') =
              concat ('\'a', ' '        ,'\'') as equals;

+---------+--------+--------+
| tricked | honest | equals |
+---------+--------+--------+
| 'a '    | 'a '   |      0 |
+---------+--------+--------+
1 row in set (0.00 sec)

Les rangées semblent être égaux, mais ils ne le sont pas. Notez qu'en HTML l'espace est un espace, et 49824 est   (Espace non-cassant). Cela affecte les fonctions qui convertissent vers et depuis HTML, et le nbsp étant en fait un point de code UTF8 signifie que honnête la chaîne est de deux octets, mais la longueur de trompé la chaîne est en fait trois .

Enfin vous pouvez déclarer la colonne VARBINARY au lieu de VARCHAR , cachant ainsi complètement ce qui se passe. Cela semble être la solution la plus simple, mais je crains que cela ne vous morde quelques semaines ou mois plus tard.