2009-01-27 4 views
8

J'ai actuellement le fonctionnement de requête sur Postgres:Pourquoi ma requête avec LIKE '% _' retourne-t-elle toutes les lignes et pas seulement celles qui se terminent par un trait de soulignement?

SELECT * FROM addenda.users WHERE users.username LIKE '%\_' 

Mais plutôt que de retourner les entrées qui se termine dans un trait de soulignement, je reviens tous les résultats, indépendamment du fait qu'il contient un trait de soulignement ou non.

L'exécution de la requête retourne en dessous d'un nom d'utilisateur qui est juste un trait de soulignement, de sorte que le Escaping fonctionne le:

SELECT * FROM addenda.users WHERE users.username LIKE '\_' 

Et d'exécuter la requête retourne en dessous d'un nom d'utilisateur qui se termine par une lettre spécifique (s):

SELECT * FROM addenda.users WHERE users.username LIKE '%s' 

Qu'est-ce que je fais mal?

Répondre

16

Votre barre oblique inverse ne passe-t-elle pas à PostgreSQL? Si vous passez la chaîne à travers un autre calque qui traite la barre oblique inverse comme un caractère d'échappement (par exemple une chaîne Java), cette couche peut supprimer la barre oblique inverse et vous devrez peut-être échapper votre barre oblique inverse pour ce calque.

Avez-vous d'autres noms d'utilisateur à caractère unique? Si la barre oblique inverse ne passait pas à PostgreSQL ils correspondraient également au critère '_'

Vous pourriez être en mesure d'essayer le ESCAPE clause: username LIKE '%!_' ESCAPE '!'

+0

Je cours la requête directement sur le serveur afin que la barre oblique inverse passe. J'ai juste essayé d'utiliser la commande ESCAPE et ça l'a fait fonctionner exactement comme je veux! –

+1

Lors de l'insertion d'une chaîne dans une instruction préparée, '\ _' correspond au caractère de soulignement, mais lorsque l'instruction sql a une chaîne littérale, vous avez besoin de' \\ _ 'à la place. Je devine que c'est parce que le premier '\' échappe au second '\' au niveau littéral de la chaîne, puis au niveau postgres il voit '\ _' dans la chaîne et le fait correspondre au caractère de soulignement. –

+0

Cela dépend en grande partie de votre réglage 'standard_conforming_strings' s'il est désactivé, vous devez doubler le' \ 'et mettre' e' avant le guillemet. s'il est allumé, un seul \ "est nécessaire. – Jasen

2

Il a été un moment que je l'ai utilisé Postgres, mais je pense que vous pouvez faites '% [_]' pour obtenir ce que vous voulez. Cela fonctionne certainement sur le serveur SQL, bien que je n'ai pas de configuration de base de données postgres maintenant pour l'essayer

+1

Non cette extension non standard à SQL n'est pas présente dans postgres. – Jasen

5

"_" est le caractère générique à un seul caractère dans la plupart des variantes SQL. Vous devez y échapper si vous voulez faire correspondre un personnage "_".

2

Vous devez remplacer la barre oblique inverse sur votre requête avec un double un, comme celui-ci:

SELECT * FROM addenda.users WHERE users.username LIKE '%\\_'

Pourtant, vous pouvez obtenir une utilisation non standard de \\ dans une chaîne littérale avertissement, mais la requête être exécuté.
Testé dans Postgres 8.4.

Questions connexes