sql >> Databáze >  >> RDS >> Mysql

MySQL 5.5 ztrácí v dotazu koncové mezery

Toto chování je záměrné, nejen v MySQL.

Můžete to obejít pomocí porovnání pomocí 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)

ale ne o moc víc. To vám pomůže s SELECT s pokud se objeví mezery, např. v uživatelském vstupu do vyhledávání; ale pokud chcete skutečně vložit informace s mezerami, bude to problém (nemůžete mít index s 'a' i 'a').

Viz také

Koncové mezery v potřebách varchar ke zvážení ve srovnání

Možná byste to mohli obrátit řetězce v tomto sloupci a při jejich zobrazení je obrátit zpět. Samozřejmě to zničí jakékoli řazení založené na tomto sloupci, ale pokud otestujete pouze rovnost nebo existenci podřetězců, může to fungovat. Vedoucí mezery se počítají.

Pro hledání rovnosti můžete také uložit kódování base64 řetězce, které by mělo zachovat lexikografické pořadí (tj. pořadí mezi a a b by mělo být zachováno mezi base64(a) a base64(b)). Nebo můžete k řetězci připojit terminátor ("\n" může fungovat dobře a neobjevuje se ve vyhledávání).

Konečně, ale je to riskantní, protože lidé nemohou rozlišit, můžete mezery nahradit znakem 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)

Řádky vypadají být si rovni, ale nejsou. Všimněte si, že v HTML je mezera mezera a 49824 je   (nepřerušitelný prostor). To má vliv na funkce, které se převádějí do HTML a zpět, a nbsp, které je ve skutečnosti kódový bod UTF8, znamená, že čestné řetězec je dva bajty, ale délka podvedený řetězec je ve skutečnosti tři .

Nakonec můžete deklarovat sloupec VARBINARY místo VARCHAR , čímž zcela skryjete, co se děje. Vypadá to jako nejjednodušší řešení, ale obávám se, že by vás to mohlo po několika týdnech nebo měsících kousnout.



  1. PDO::FETCH_ASSOC nenačítá vše

  2. Sloučení datových souborů se Statistica, část 2

  3. Počítejte odlišné hodnoty

  4. Vypočítejte rozdíl mezi dvěma daty v hodinách a minutách