Comparaison de chaîne d'exact dans la requête MySQL
J'ai créé une table comme ça dans MySQL:
DROP TABLE IF EXISTS `barcode`;
CREATE TABLE `barcode` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`code` varchar(40) COLLATE utf8_bin DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
INSERT INTO `barcode` VALUES ('1', 'abc');
INSERT INTO `barcode` VALUES ('2', 'abc ');
Puis-je interroger les données de la table de codes à barres:
SELECT * FROM barcode WHERE `code` = 'abc ';
Le résultat est:
+-----+-------+
| id | code |
+-----+-------+
| 1 | abc |
+-----+-------+
| 2 | abc |
+-----+-------+
Mais je veux que le résultat est à seulement 1 enregistrement. J'solution de contournement:
SELECT * FROM barcode WHERE `code` = binary 'abc ';
Le résultat est 1 enregistrement. Mais je suis en utilisant NHibernate avec MySQL pour la génération de requête à partir de la table de mappage. De sorte que la façon de résoudre ce cas?
La prochaine fois, regardez comment votre question va sortir (il y a une zone d'aperçu en dessous de votre zone de texte), et si elle ressemble à un gâchis, résoudre le problème :). Utilisez une quantité généreuse de la
Pourriez-vous fournir NHibenate mappages, et les méthodes que vous utilisez pour générer une requête? Pourquoi utilisez-vous le natif SQL avec NHibernate. Je pense que vous devriez utiliser les Critères de l'API ou HQL.
à partir de la documentation: "Tous les MySQL classements sont de type PADSPACE. Cela signifie que toutes les valeurs CHAR et VARCHAR dans MySQL sont comparés, sans égard à toute trailing spaces">
{}
bouton sur le dessus pour le code.....Pourriez-vous fournir NHibenate mappages, et les méthodes que vous utilisez pour générer une requête? Pourquoi utilisez-vous le natif SQL avec NHibernate. Je pense que vous devriez utiliser les Critères de l'API ou HQL.
à partir de la documentation: "Tous les MySQL classements sont de type PADSPACE. Cela signifie que toutes les valeurs CHAR et VARCHAR dans MySQL sont comparés, sans égard à toute trailing spaces">
OriginalL'auteur Tang Khai Phuong | 2012-04-27
Vous devez vous connecter pour publier un commentaire.
Il n'y a pas d'autre solution pour elle. Soit vous spécifiez une seule comparaison comme étant
binary
ou vous réglez la totalité de la base de données connexion àbinary
. (faireSET NAMES binary
, ce qui peut avoir d'autres effets secondaires!)À la base, c' 'lazy' comparaison est un fonction de MySQL, qui est codé en dur. Pour le désactiver (sur demande!), vous pouvez utiliser un
binary
comparer, ce qu'apparemment vous avez déjà. Ce n'est pas une "solution de contournement", mais la vraie solution.de la Manuel MySQL:
Bien sûr, il ya beaucoup d'autres possibilités pour obtenir le même résultat à partir d'un point de vue utilisateur, c'est à dire:
WHERE field = 'abc ' AND CHAR_LENGTH(field) = CHAR_LENGTH('abc ')
WHERE field REGEXP 'abc[[:space:]]'
Le problème avec ces derniers est qu'ils ont effectivement désactiver rapide de la recherche d'index, de sorte que votre requête est toujours un full table scan. Avec d'énormes ensembles de données qui fait une grande différence.
De nouveau:
PADSPACE
est par défaut pour MySQLs [VAR]CHAR de comparaison. Vous pouvez (et devez) le désactiver en utilisantBINARY
. C'est le indended moyen de le faire.OriginalL'auteur Kaii
Vous pouvez essayer avec un expression régulière correspondant :
Je suppose que cette réponse a été downvoted parce que
REGEXP
désactive la recherche d'index et toujours les résultats dans une table pleine de numérisation. Si vous peut éviter la regex dans mysql, vous ne devriez pas l'utiliser.OriginalL'auteur aleroot
Vous pourriez faire ceci:
Je suppose que cette réponse a été downvoted parce que
WHERE F(x) = F(y)
est à l'origine de calcul des frais généraux, parce que la fonction doit être exécutée deux fois pour chaque ligne du jeu de résultats. Dans ce cas, il n'est pas trop mauvais, car il y a au moins un simpleWHERE
condition. SiF(x) = F(y)
était le condition, il en résulterait un full table scan, qui est quelque chose que vous devriez éviter.OriginalL'auteur Arion
Je suis en supposant que vous voulez seulement un résultat, vous pouvez utiliser
LIMIT
Faire exacte correspondance de chaîne vous pouvez utiliser
Collation
LIMIT
ne l'atteignent pas.Je ne pense pas que votre utilisation proposée de
COLLATE utf8_general_ci
qui fera toute la différence?COLLATE binary
feraitOriginalL'auteur Darren
j'étais en train de travailler sur des cas comme ça lors de l'utilisation, COMME avec des caractères génériques (%) aboutissant à un résultat inattendu. En cherchant j'ai aussi trouvé
STRCMP(text1, text2)
en vertu de comparaison de chaînes en fonction de mysql qui compare deux chaînes de caractères. cependant, l'utilisation des BINAIRES avec COMME résolu le problème pour moi.mon mauvais. je dois ajouter quelques explications. merci de me laisser savoir.
OriginalL'auteur R T
La phrase juste après celui cité par Kaii dit en gros "utilisation
LIKE
" :et l'exemple ci-dessous montre que
'Monty' = 'Monty '
est vrai, mais pas'Monty' LIKE 'Monty '
.Toutefois, si vous utilisez
LIKE
, méfiez-vous des chaînes de caractères littérales contenant le'%'
,'_'
ou'\'
caractères :'%'
et'_'
sont des caractères génériques,'\'
est utilisé pour les séquences d'échappement.LIKE
, il faut également être conscient de l'autre côté des effets de laLIKE
de l'opérateur. Exemples:"A" LIKE "a"
est égal à true,"a" LIKE "_"
aussi est égale à true. Comme une solution de contournement à l'insensibilité à la casse deLIKE
le manuel propose unLIKE BINARY
opération .. Et c'est là que le cercle est fermé:BINARY
est la vraie solution. Si vous ne me croyez pas, consultez le manuel deLIKE
. La seule différence entre= BINARY
etLIKE BINARY
est queLIKE
a plus d'effets secondaires. Désolé 😉Ok, merci pour les détails supplémentaires.
"A" LIKE "a"
dépend du classement, n'est-ce pas ? tout comme=
. Je n'étais pas au courant de la"_"
caractère spécial. C'est sûr qu'il ne fait que compliquer le cas du coin. Merci pour cette remarque.Vous avez raison,
"A" LIKE "a"
dépend de classement."A" COLLATE utf8_bin LIKE "a" COLLATE utf8_bin
ne retour0
.OriginalL'auteur LeGEC