Как я должен экранировать символы внутри этого запроса LIKE? - PullRequest
5 голосов
/ 07 сентября 2011

У меня есть поле в одной из моих таблиц, которое содержит эту строку:

!"#¤%&/()=?´`?=)(/&%¤#"!\'\'"'

(Только для целей тестирования курса).Я пробовал бесконечные запросы, чтобы правильно выбрать это поле и, конечно же, не возвращая никаких ошибок, но я просто не могу понять, что это правильно.

Этот запрос я использую в настоящее время:1006 *

SELECT * FROM mytable WHERE `column` LIKE '%!"#¤%&/()=?´`?=)(/&%¤#"!\\\'\\\'"\'%'

Может кто-нибудь пролить свет на то, что я делаю неправильно?Есть ли какие-либо другие символы (кроме '), которые я должен убежать?Я нигде не читал об этом ... (однако я попытался добавить обратную косую черту перед символами прецента).

Ответы [ 3 ]

7 голосов
/ 05 июля 2014

С MySQL Manual :

Поскольку MySQL использует синтаксис C в строках (например, «\n» для представления символа новой строки), вы должны удвоить любой «\», который вы используете в LIKE строках. Например, для поиска «\n» укажите его как «\\n». Для поиска «\» укажите его как «\\\\»; это связано с тем, что обратный слеш удаляется парсером один раз и снова, когда выполняется сопоставление с образцом, оставляя один обратный слеш для сопоставления.

Итак, вы должны экранировать строку для оператора LIKE в два этапа.

В PHP это может быть так:

// Your search string, for example, from POST field
$string = $_POST['column'];

// First step - LIKE escaping
$string = str_replace(array('\\', '_', '%'), array('\\\\', '\\_', '\\%'), $string);

// Second step - literal escaping
$string = mysql_real_escape_string($string);

// Result query
mysql_query("SELECT * FROM `table` WHERE `column` LIKE '%".$string."%'");

UPDATE:

Расширение MySQL устарело в PHP 5.5.0 и удалено в PHP 7.0.0. Вместо этого следует использовать расширение MySQLi или PDO_MySQL .

Использовать MySQLi

// Connect to database
$mysqli = new mysqli('localhost', 'username', 'password', 'database');

// Your search string, for example, from POST field
$string = $_POST['column'];

// First step - LIKE escaping
$string = str_replace(['\\', '_', '%'], ['\\\\', '\\_', '\\%'], $string);

// Second step - literal escaping
$string = $mysqli->real_escape_string($string);

// Result query
$mysqli->query("SELECT * FROM `table` WHERE `column` LIKE '%{$string}%'");

Использовать PDO

// Connect to database
$conn = new PDO('mysql:host=localhost;dbname=database', 'username', 'password');

// Your search string, for example, from POST field
$string = $_POST['column'];

// First step - LIKE escaping
$string = str_replace(['\\', '_', '%'], ['\\\\', '\\_', '\\%'], $string);

// Second step - literal escaping
$string = $conn->quote($string);

// Result query
$conn->query("SELECT * FROM `table` WHERE `column` LIKE '%{$string}%'");

Или вы можете использовать подготовленный оператор PDO вместо второго шага (экранирование букв):

// Connect to database
$conn = new PDO('mysql:host=localhost;dbname=database', 'username', 'password');

// Your search string, for example, from POST field
$string = $_POST['column'];

// First step - LIKE escaping
$string = str_replace(['\\', '_', '%'], ['\\\\', '\\_', '\\%'], $string);

// Prepare a statement for execution
$statement = $conn->prepare("SELECT * FROM `table` WHERE `column` LIKE ?");

// Execute a prepared statement
$statement->execute(["%{$string}%"]);
2 голосов
/ 07 сентября 2011

Не ясно, что вы пытаетесь получить и что идет не так.

Кстати, если вы хотите защитить свой запрос от SQL-инъекции, вы должны использовать mysql_real_escape_string
http://dev.mysql.com/doc/refman/5.0/en/mysql-real-escape-string.html

Предполагая, что вы находитесь в PHP

$query = "SELECT * FROM mytable WHERE `column` LIKE '".mysql_real_escape_string($whatever)."'"

Но вы должны помнить, что у оператора LIKE есть свои специальные символы (wildchars)
http://dev.mysql.com/doc/refman/5.0/en/string-comparison-functions.html#operator_like

% Matches any number of characters, even zero characters
_ Matches exactly one character

Таким образом, эти символы должны быть экранированы с помощью обратной косой черты, если вы хотите остановить их magic

Если вы находитесь в PHP, я бы сделал

// This removes magic on LIKE wildchars
$whatever = preg_replace('#(%|_)#', '\\$1', $input);

// This secures the query from sql injection 
// and hads the trailing % wildchars to the search string
$query = "SELECT * FROM mytable WHERE `column` LIKE '%".mysql_real_escape_string($whatever)."%'"
0 голосов
/ 07 сентября 2011

Вы используете PHP?Если это так, вы можете попробовать что-то вроде:

$a = mysql_real_escape_string('%!"#¤%&/()=?´`?=)(/&%¤#"!\'\'"\'%');
$query_string = "SELECT * FROM mytable WHERE `column` LIKE '$a'";

Это решит вашу проблему?

...