Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Escaping von MySQL-Wildcards

_ und % sind in MySQL im Allgemeinen keine Platzhalter und sollten nicht maskiert werden, um sie in normale Zeichenfolgenliterale einzufügen. mysql_real_escape_string ist für diesen Zweck richtig und ausreichend. addcslashes sollte nicht verwendet werden.

_ und % sind nur im Zusammenhang mit LIKE besonders -passend. Wenn Sie Zeichenfolgen für die wörtliche Verwendung in einem LIKE vorbereiten möchten Anweisung, sodass 100% hundertprozentig übereinstimmt und nicht irgendeine Zeichenfolge, die mit hundert beginnt, müssen Sie sich um zwei Ebenen des Entkommens kümmern.

Das erste ist WIE zu entkommen. Die LIKE-Verarbeitung findet vollständig innerhalb von SQL statt, und wenn Sie einen Literal-String in einen Literal-LIKE-Ausdruck umwandeln möchten, müssen Sie diesen Schritt auch dann ausführen, wenn Sie parametrisierte Abfragen verwenden !

In diesem Schema _ und % sind etwas Besonderes und müssen entkommen werden. Das Escape-Zeichen muss ebenfalls maskiert werden. Laut ANSI SQL dürfen andere Zeichen nicht maskiert werden:\' wäre falsch. (Obwohl MySQL Sie normalerweise damit durchkommen lässt.)

Nachdem Sie dies getan haben, fahren Sie mit der zweiten Escape-Ebene fort, die das einfache alte String-Literal-Escape ist. Dies geschieht außerhalb von SQL, indem SQL erstellt wird, also muss es nach dem LIKE-Escape-Schritt erfolgen. Für MySQL ist dies mysql_real_escape_string wie vorher; für andere Datenbanken wird es eine andere Funktion geben, bei der Sie einfach parametrisierte Abfragen verwenden können, um dies zu vermeiden.

Das Problem, das hier zu Verwirrung führt, ist, dass in MySQL ein Backslash als Escape-Zeichen für beide verschachtelten Escape-Schritte verwendet wird! Wenn Sie also eine Zeichenfolge mit einem wörtlichen Prozentzeichen vergleichen möchten, müssen Sie einen doppelten Backslash-Escape ausführen und LIKE 'something\\%' sagen . Oder, wenn das in einem PHP " steht Literal, das auch Backslash-Escapezeichen verwendet, "LIKE 'something\\\\%'" . Argh!

Dies ist laut ANSI SQL falsch, das besagt:In String-Literalen bedeuten umgekehrte Schrägstriche wörtliche umgekehrte Schrägstriche, und der Weg, ein einfaches Anführungszeichen zu maskieren, ist ''; in LIKE-Ausdrücken gibt es standardmäßig überhaupt kein Escape-Zeichen.

Wenn Sie also auf tragbare Weise LIKE-escapen möchten, sollten Sie das standardmäßige (falsche) Verhalten überschreiben und Ihr eigenes Escape-Zeichen angeben, indem Sie den LIKE ... ESCAPE ... verwenden bauen. Aus Gründen der Vernunft wählen wir etwas anderes als den verdammten umgekehrten Schrägstrich!

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 ...";

oder mit Parametern (zB in PDO):

$q= $db->prepare("... WHERE name LIKE ? ESCAPE '=' AND ...");
$q->bindValue(1, '%'.like($name, '=').'%', PDO::PARAM_STR);

(Wenn Sie mehr Partyzeit für die Portabilität wünschen, können Sie auch Spaß daran haben, MS SQL Server und Sybase zu berücksichtigen, wo der [ Zeichen ist auch fälschlicherweise ein Sonderzeichen in einem LIKE Anweisung und muss maskiert werden. argh.)