2009-05-19 33 views
50

Per esempio:Come faccio a sfuggire a caratteri speciali in MySQL?

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

Errore:

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'hi" "' at line 1

Come faccio a costruire questa ricerca?

risposta

78

The information provided in this answer can lead to insecure programming practices.

The information provided here depends highly on MySQL configuration, including (but not limited to) the program version, the database client and character-encoding used.

Vedi 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. 

Quindi è necessario

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

Anche se come Bill Karwin notes below, utilizzando i doppi apici per delimitare le stringhe non è SQL standard, quindi è buona norma utilizzare le virgolette singole . Questo semplifica le cose:

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

È possibile utilizzare mysql_real_escape_string. mysql_real_escape_string() non sfugge a % e _, quindi è necessario sfuggire ai caratteri jolly MySQL (% e _) separatamente.

24

È necessario utilizzare virgolette singole per i delimitatori di stringhe. La virgola singola è il delimitatore di stringhe SQL standard e le virgolette sono delimitatori identificatori (in modo da poter utilizzare parole o caratteri speciali nei nomi di tabelle o colonne).

In MySQL, le virgolette funzionano (non standard) come delimitatori di stringhe per impostazione predefinita (a meno che non si imposti la modalità SQL ANSI). Se utilizzi un'altra marca di database SQL, potrai trarre vantaggio dall'abitudine a utilizzare le quotazioni in modo standard.

Un altro utile vantaggio di utilizzare apostrofi è che i caratteri a doppio virgolette letterali all'interno la stringa non hanno bisogno di essere sfuggito:

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

Sono d'accordo con l'idea single-preventivo, perché se si passa a Ad esempio, PostgresSQL rifiuta ostinatamente le tue query e devi utilizzare le virgolette singole. È una buona pratica – kovacsbv

26

ho sviluppato il mio metodo di fuga MySQL in Java (se utile per chiunque).

Vedi codice di classe qui sotto.

Avviso: errato se NO_BACKSLASH_ESCAPES la modalità SQL è abilitata.

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(); 
} 
+0

Utilizzato la ricerca sostituire la tabella in una procedura mysql in cui ho bisogno di uscire da un delimitatore di tabulazione per essere inserito correttamente nel db come '\ t'. grazie –

9

MySQL ha la funzione di stringa QUOTE, e dovrebbe risolvere questo problema:

4

Per le stringhe come quella, per me il modo più comodo per farlo sta raddoppiando la 'o", come spiegato nel manuale di MySQL:

There are several ways to include quote characters within a string:

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 

Strings quoted with “'” need no special treatment.

E 'da http://dev.mysql.com/doc/refman/5.0/en/string-literals.html

0

Se. Stai usando una variabile durante la ricerca in una stringa, mysql_real_escape_string() fa bene. Solo il mio suggerimento:

$char = "and way's 'hihi'"; 
$myvar = mysql_real_escape_string($char); 

select * from tablename where fields like "%string $myvar %"; 
+0

Questa funzione è ammortizzata in PHP 5.5 e rimossa da 7.0 –

0

Per testare come inserire le virgolette in MYSQL utilizzando Terminal è possibile utilizzare il seguente modo.

TableName(Name,DString) - > Schema
insert into TableName values("Name","My QQDoubleQuotedStringQQ")


dopo aver inserito il valore è possibile aggiornare il valore nel db con virgolette doppie o singole

update table TableName replace(Dstring,"QQ","\"")

Problemi correlati