91 votes

Comment puis-je échapper aux caractères spéciaux dans MySQL ?

Par exemple :

select * from tablename where fields like "%string "hi"  %";

Erreur :

Vous avez une erreur dans la syntaxe SQL ; consultez le manuel correspondant à la version de votre serveur MySQL pour connaître la syntaxe à utiliser près de 'hi" "' à la ligne 1.

Comment puis-je construire cette requête ?

124voto

Paul Dixon Points 122033

Les informations fournies dans cette réponse peuvent conduire à des pratiques de programmation non sécurisées.

Les informations fournies ici dépendent fortement de la configuration de MySQL, notamment (mais pas uniquement) de la version du programme, du client de la base de données et du codage des caractères utilisé.

Voir http://dev.mysql.com/doc/refman/5.0/en/string-literals.html

MySQL recognizes the following escape sequences.
\\0     An ASCII NUL (0x00) character.
\\'     A single quote (“'”) character.
\\"     A double quote (“"”) character.
\\b     A backspace character.
\\n     A newline (linefeed) character.
\\r     A carriage return character.
\\t     A tab character.
\\Z     ASCII 26 (Control-Z). See note following the table.
\\\\     A backslash (“\\”) character.
\\%     A “%” character. See note following the table.
\\\_     A “\_” character. See note following the table.

Donc vous avez besoin

select * from tablename where fields like "%string \"hi\" %";

Bien que comme Bill Karwin note ci-dessous L'utilisation de guillemets doubles pour délimiter les chaînes de caractères n'est pas une norme SQL ; il est donc préférable d'utiliser des guillemets simples. Cela simplifie les choses :

select * from tablename where fields like '%string "hi" %';

39voto

Walid Points 786

J'ai développé ma propre méthode d'échappement MySQL en Java (si cela peut être utile à quelqu'un).

Voir le code de classe ci-dessous.

Warning : incorrect si le mode SQL NO_BACKSLASH_ESCAPES est activé.

private static final HashMap<String,String> sqlTokens;
private static Pattern sqlTokenPattern;

static
{           
    //MySQL escape sequences: http://dev.mysql.com/doc/refman/5.1/en/string-syntax.html
    String[][] search_regex_replacement = new String[][]
    {
                //search string     search regex        sql replacement regex
            {   "\u0000"    ,       "\\x00"     ,       "\\\\0"     },
            {   "'"         ,       "'"         ,       "\\\\'"     },
            {   "\""        ,       "\""        ,       "\\\\\""    },
            {   "\b"        ,       "\\x08"     ,       "\\\\b"     },
            {   "\n"        ,       "\\n"       ,       "\\\\n"     },
            {   "\r"        ,       "\\r"       ,       "\\\\r"     },
            {   "\t"        ,       "\\t"       ,       "\\\\t"     },
            {   "\u001A"    ,       "\\x1A"     ,       "\\\\Z"     },
            {   "\\"        ,       "\\\\"      ,       "\\\\\\\\"  }
    };

    sqlTokens = new HashMap<String,String>();
    String patternStr = "";
    for (String[] srr : search_regex_replacement)
    {
        sqlTokens.put(srr[0], srr[2]);
        patternStr += (patternStr.isEmpty() ? "" : "|") + srr[1];            
    }
    sqlTokenPattern = Pattern.compile('(' + patternStr + ')');
}

public static String escape(String s)
{
    Matcher matcher = sqlTokenPattern.matcher(s);
    StringBuffer sb = new StringBuffer();
    while(matcher.find())
    {
        matcher.appendReplacement(sb, sqlTokens.get(matcher.group(1)));
    }
    matcher.appendTail(sb);
    return sb.toString();
}

27voto

Bill Karwin Points 204877

Vous devez utiliser des guillemets simples pour les délimiteurs de chaîne. Les guillemets simples sont le délimiteur de chaîne SQL standard, tandis que les guillemets doubles sont des délimiteurs d'identifiant (vous pouvez donc utiliser des mots ou des caractères spéciaux dans les noms des tables ou des colonnes).

Dans MySQL, les guillemets doubles fonctionnent (de manière non standard) comme délimiteur de chaîne par défaut (à moins que vous ne définissiez le paramètre ANSI mode SQL). Si vous utilisez un jour une autre marque de base de données SQL, vous gagnerez à prendre l'habitude d'utiliser les guillemets de manière standard.

Un autre avantage pratique de l'utilisation des guillemets simples est que les caractères entre guillemets littéraux dans votre chaîne n'ont pas besoin d'être échappés :

select * from tablename where fields like '%string "hi" %';

14voto

DaiHadi Points 36

MySQL dispose de la fonction chaîne QUOTE et cela devrait résoudre le problème

9voto

Raúl Moreno Points 17

Pour les chaînes de caractères de ce type, la façon la plus confortable de procéder est de doubler le ' ou le ", comme expliqué dans le manuel MySQL :

Il existe plusieurs façons d'inclure des caractères guillemets dans une chaîne de caractères :

A “'” inside a string quoted with “'” may be written as “''”.

A “"” inside a string quoted with “"” may be written as “""”.

Precede the quote character by an escape character (“\”).

A “'” inside a string quoted with “"” needs no special treatment and need not be doubled or escaped. In the same way, “"” inside a

Les chaînes de caractères citées avec "'" ne nécessitent pas de traitement particulier.

Il s'agit de http://dev.mysql.com/doc/refman/5.0/en/string-literals.html .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X