2012-05-08 6 views
8

Se la riga del database è simile a questa: country = 'usa' e viene interrotta la query "select * from data where country = 'usa '", viene restituita anche questa riga. Quindi non è una corrispondenza esatta.Operatore di confronto MySQL, spazi

Perché MySQL esegue questa operazione? E in quali altri casi restituirà VERO quando non è proprio vero?

risposta

4

Gli spazi finali vengono omessi se la colonna è di tipo char o varchar; utilizzando like 'usa ' risolve il problema

+0

+1, http://dev.mysql.com/doc/refman/5.0/en/char.html, quando i valori CHAR vengono recuperati, spazi finali vengono rimossi. –

0

provare con like o con questo

country = 'usa ' AND LENGTH(country) = LENGTH('usa ') 
9

Come accennato in the manual:

Tutte le regole di confronto di MySQL sono di tipo PADSPACE. Ciò significa che tutti i valori e VARCHAR in MySQL vengono confrontati indipendentemente dagli spazi finali.

Nella definizione di operatore LIKE, afferma:

In particolare, spazi finali sono significativi, che non è vero per CHAR o VARCHAR confronti eseguiti con l'operatore =:

Come indicato in this answer:

Questo comportamento è specificato in SQL-92 e SQL: 2008. Ai fini del confronto, la stringa più breve viene riempita alla lunghezza della stringa più lunga.

dal progetto (8.2 < comparatore predicato >):

Se la lunghezza in caratteri di X non è uguale alla lunghezza in caratteri di Y, allora la stringa più corta viene effettivamente sostituito, ai fini di confronto, con una copia di se stesso che è stata estesa alla lunghezza della stringa più lunga mediante concatenazione a destra di uno o più caratteri pad, in cui il carattere pad viene scelto in base a CS. Se CS ha la caratteristica NO PAD, allora il carattere pad è un personaggio dipendente dall'implementazione diverso da qualsiasi carattere nel set di caratteri di X e Y che raccoglie meno di qualsiasi stringa in CS. In caso contrario, il carattere del riquadro è uno spazio < >.

Oltre alle altre soluzioni eccellenti:

select binary 'a' = 'a ' 
+0

Risposta molto bella –

+0

@eggyal, Quindi qual è la ** correzione **? – Pacerier

0

Il manuale dice questo:

Tutte le regole di confronto MySQL sono di tipo PADSPACE. Ciò significa che tutti i valori CHAR e VARCHAR in MySQL vengono confrontati indipendentemente dagli spazi finali [...] Ciò vale per tutte le versioni di MySQL e non è influenzato dalla modalità SQL del server.

http://dev.mysql.com/doc/refman/5.5/en/char.html

Se è necessario considerare lo spazio vuoto, che, fondamentalmente, di sbarazzarsi di smistamento lingua-aware. Un modo semplice è forzare una collazione binaria. Eseguire e confronta:

SELECT 'ab'='ab ', BINARY 'ab'='ab ' 
+0

Osservazione pedante eccellente: l'operatore 'BINARY' qui non sta" forzando una collazione binaria ", che verrebbe eseguita applicando una clausola' COLLATE * _bin', ma piuttosto sta lanciando il suo operando non binario a una stringa binaria: l'effetto di così facendo è che il confronto è esattamente byte per byte, che è simile a quello che farebbe una collazione binaria (eccetto che le regole binarie sono ancora PADSPACE). I lettori potrebbero ritenere utile conoscere questa differenza, spiegata in modo più dettagliato nella sezione del manuale [The _bin e binary Collations] (https://dev.mysql.com/doc/en/charset-binary-collations.html) . – eggyal

+0

Grazie, questi chiarimenti non sono mai fuori luogo. Non avrei nemmeno scartato che avevo in mente un "confronto binario", ma lo ho semplicemente scritto male: lo faccio abbastanza spesso :) –