Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Escapando curingas do MySQL


_ e % não são curingas no MySQL em geral e não devem ser escapados para fins de colocá-los em literais de string normais. mysql_real_escape_string é correto e suficiente para este fim. addcslashes não deve ser usado.

_ e % são especiais apenas no contexto de LIKE -Coincidindo. Quando você deseja preparar strings para uso literal em um LIKE declaração, para que 100% corresponde a cem por cento e não apenas qualquer string começando com cem, você tem dois níveis de escape para se preocupar.

O primeiro é como escapar. O tratamento LIKE ocorre inteiramente dentro do SQL, e se você quiser transformar uma string literal em uma expressão LIKE literal, você deve executar esta etapa mesmo se estiver usando consultas parametrizadas !

Neste esquema, _ e % são especiais e devem ser evitados. O caractere de escape também deve ser escapado. De acordo com o ANSI SQL, caracteres diferentes desses não devem ser escapado:\' estaria errado. (Embora o MySQL normalmente deixe você se safar.)

Tendo feito isso, você prossegue para o segundo nível de escape, que é o escape literal de cadeia de caracteres simples. Isso ocorre fora do SQL, criando o SQL, portanto, deve ser feito após a etapa de escape LIKE. Para MySQL, este é mysql_real_escape_string como antes; para outros bancos de dados haverá uma função diferente, você pode apenas usar consultas parametrizadas para evitar ter que fazer isso.

O problema que leva à confusão aqui é que no MySQL usa uma barra invertida como um caractere de escape para ambas as etapas de escape aninhadas! Portanto, se você quisesse corresponder uma string a um sinal de porcentagem literal, teria que usar a barra invertida e escapar e dizer LIKE 'something\\%' . Ou, se estiver em um PHP " literal que também usa escape de barra invertida, "LIKE 'something\\\\%'" . Argh!

Isso está incorreto de acordo com o ANSI SQL, que diz que:em literais de string, barras invertidas significam barras invertidas literais e a maneira de escapar de uma aspa simples é ''; em expressões LIKE não há nenhum caractere de escape por padrão.

Portanto, se você deseja LIKE-escape de maneira portátil, deve substituir o comportamento padrão (errado) e especificar seu próprio caractere de escape, usando o LIKE ... ESCAPE ... construir. Por sanidade, escolheremos algo diferente da maldita barra invertida!
function like($s, $e) {
    return str_replace(array($e, '_', '%'), array($e.$e, $e.'_', $e.'%'), $s);
}

$escapedname= mysql_real_escape_string(like($name, '='));
$query= "... WHERE name LIKE '%$escapedname%' ESCAPE '=' AND ...";

ou com parâmetros (por exemplo, em PDO):
$q= $db->prepare("... WHERE name LIKE ? ESCAPE '=' AND ...");
$q->bindValue(1, '%'.like($name, '=').'%', PDO::PARAM_STR);

(Se você quiser mais tempo de festa de portabilidade, você também pode se divertir tentando contabilizar o MS SQL Server e Sybase, onde o [ caractere também é, incorretamente, especial em um LIKE declaração e tem que ser escapado. argh.)