Pourquoi «_» (trait de soulignement) correspond-il à «-» (trait d'union)?


110

Je dois chercher un manuel PDF en utilisant cette requête:

root@localhost:test> select * from a where name like '%taz_manual%.pdf%';
+--------------------+------------------+-------------+
| name               | description      |        size | 
+--------------------+------------------+-------------+
| taz-manual-1.1.pdf | Manual v1.0 TA-Z |    31351902 |
| taz-manual-0.2.pdf | Manual v1.0 T1-A |     3578278 |
| taz_manual-2.0.pdf | Manual v2.0 GA-X |   542578278 |
etc........
+--------------------+------------------+-------------+
132 row in set (0.00 sec)

Pourquoi est-ce que je vois celui avec des tirets lorsque je spécifie le nom à être taz_manual%.pdf?

Réponses:


231

Parce que le trait de soulignement _est un caractère générique comme le pourcentage %, sauf qu'il ne recherche qu'un seul caractère.

La correspondance de modèle SQL vous permet d'utiliser "_" pour faire correspondre n'importe quel caractère unique et "%" pour correspondre à un nombre arbitraire de caractères (y compris zéro caractère).

(De la section 3.3.4.7. Pattern Matching dans la documentation MySQL.)

Si vous souhaitez utiliser le trait de soulignement likecomme littéral, vous devez l'échapper:

select * from a where name like '%taz\_manual%.pdf%';

afaik cela n'est pertinent que lorsque vous êtes dans un contexte de modèle. par exemple à l'intérieur d'une LIKEdéclaration. Lors du remplacement de tous _avec -: UPDATE sys_file set identifier = REPLACE(identifier, '_', '-') WHERE identifier LIKE '%\_%';. Remarquez la fuite à l'intérieur LIKEet aucune fuite à l'intérieur REPLACE. (Je trouve étrange cependant que vous ne soyez pas dans un contexte de modèle à l'intérieur de replace ...)
Hafenkranich

@Hafenkranich du doc ​​mysql: "utiliser les opérateurs de comparaison LIKE or NOT LIKE"
Book Of Zeus

2

J'ai eu un problème similaire avec l'espace et les traits d'union lors de la correspondance des chaînes avec une correspondance exacte:

SELECT id FROM location WHERE name = 'IND - HQ';

La requête ci-dessus n'a renvoyé aucun enregistrement dans MySQL. J'ai dû échapper aux espaces et aux traits d'union et utiliser LIKEau lieu de la correspondance exacte avec égal (=) comme suit:

SELECT id FROM location WHERE name LIKE 'IND_\-_HQ';

Êtes-vous sûr que cela est lié? Peut-être qu'il n'y avait pas de ligne d'emplacement avec ce nom exact ... ???
Nico Haase

oui, il y avait des lignes avec location = 'IND - HQ' et ce qui précède a
résolu

Et vous le savez parce que vous avez posé la question à la personne qui avait cette question cinq ans avant de publier votre réponse?
Nico Haase
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.