Comment échapper à la chaîne, tout en respectant le motif dans PostgreSQL
Je veux trouver les lignes où une colonne de texte commence par un utilisateur de la chaîne de caractères, par exemple SELECT * FROM users WHERE name LIKE 'rob%'
mais "rob" est invalidée en entrée de l'utilisateur. Si l'utilisateur écrit une chaîne de caractères contenant un motif spécial caractère comme "rob_", elle correspond à la fois "robert42" et "rob_the_man". J'ai besoin d'être sûr que le string est assorti littéralement, comment dois-je procéder? Ai-je besoin pour gérer l'échappement au niveau de l'application ou est-il une plus belle façon?
Je suis en utilisant PostgreSQL 9.1 et allez-pgsql pour Aller.
OriginalL'auteur Betamos | 2012-04-14
Vous devez vous connecter pour publier un commentaire.
_ Et % caractères doivent être cités pour être appariés littéralement dans une déclaration, il n'y a pas moyen de contourner cela. Le choix est à propos de le faire côté client ou côté serveur (généralement à l'aide de SQL replace(), voir ci-dessous). Aussi pour obtenir 100% dans le cas général, il ya quelques choses à considérer.
Par défaut, la citation de caractères à utiliser avant d' _ ou % est la barre oblique inverse (\), mais il peut être modifié avec une clause de sauvegarde qui suit immédiatement la clause LIKE.
Dans tous les cas, le caractère de devis doit être répétée deux fois dans le modèle pour être assorti à la lettre comme un caractère.
Exemple:
... WHERE field like 'john^%node1^^node2.uucp@%' ESCAPE '^'
correspondent à jean%node1^node2.dernier@ suivie par quoi que ce soit.Il y a un problème avec le choix par défaut de la barre oblique inverse: il est déjà utilisé pour d'autres fins lorsque standard_conforming_strings est DÉSACTIVÉ (PG 9.1 a SUR par défaut, mais les versions précédentes étant encore dans une large utilisation, c'est un point à prendre en considération).
Également si le citant COMME caractère générique est fait côté client dans une entrée de l'utilisateur injection scénario, il s'agit en plus de à la normale à la chaîne, citant déjà nécessaire à la saisie de l'utilisateur.
Un coup d'œil à un aller-pgsql exemple indique qu'il utilise $N-style espaces réservés pour les variables... voici Donc une tentative d'écriture dans un peu une façon générique: il fonctionne avec standard_conforming_strings à la fois SUR on ou OFF, utilise le serveur-côté de remplacement de [%_], une autre citation de caractères, la mention de la citation de caractères, et évite l'injection sql:
OriginalL'auteur Daniel Vérité
Échapper le trait de soulignement et le pour cent à être utilisé dans un modèle en
like
expressions utiliser le caractère d'échappement:Je pense qu'il ne gère pas le cas où \ apparaît dans l'entrée de l'utilisateur. J'ai soumis une autre réponse qui, je l'espère couvre tout.
OriginalL'auteur Clodoaldo Neto
Aussi loin que je peux dire uniquement des caractères spéciaux avec l'opérateur LIKE pour cent et le trait de soulignement, et ceux-ci peuvent facilement être échappé manuellement à l'aide de la barre oblique inverse. C'est pas très beau, mais il fonctionne.
Je trouve ça étrange qu'il n'existe pas de telles fonctions de livré avec PostgreSQL. Qui veut que ses utilisateurs d'écrire leurs propres modèles?
Deux ou trois
replace()
les appels sont généralement beaucoup plus rapide qu'une seuleregexp_replace()
appel. Vous devriez aller avec Daniel est très bien pensé réponse.Si vous allez dans cette voie, vous devez également échapper à la
'\'
depuis la chaîne d'entrée pourrait être quelque chose comme'rob\%'
, donc si vous remplacez'%'
avec'\%'
, vous vous retrouverez avec'rob\\%'
, ce qui est exact/literal'rob\'
puis'%'
génériqueOriginalL'auteur Betamos
La meilleure réponse est que vous ne devriez pas être d'interpolation de saisie de l'utilisateur dans votre sql. Même s'échappant du sql est toujours dangereux.
Le suivant qui utilise go db/sql bibliothèque illustre d'une façon beaucoup plus sécuritaire. Remplacer le Préparer et Exec appels avec tout ce que votre go postgresql de la bibliothèque sont équivalents.
Les avantages sont que la saisie de l'utilisateur peut en toute sécurité être utilisés sans crainte de l'injection de code sql dans les déclarations que vous exécutez. Vous obtenez également les avantages de la réutilisation de l'préparé sql pour les requêtes multiples qui peut être plus efficace dans certains cas.
OriginalL'auteur Jeremy Wall