Подготовительный запрос не может вернуть результаты, если условие LIKE содержит более одного подстановочного знака - PullRequest
0 голосов
/ 03 июля 2019

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

Я попытался выполнить много форм запроса без удачи. Я настроил параметры сортировки для таблицы и полей, чтобы добавить нечувствительность к регистру. Я искал похожие посты, но не смог найти. Я также просмотрел документацию по MySQL prepare и like. Сначала я использовал PHP PDO-соединение со значительно более сложным запросом, но сузил его до простого SELECT и изолировал его для подготовки MySQL.


* Все эти запросы были выполнены в MySQL Workbench

PREPARE stm FROM "SELECT firstName, lastName, displayName FROM `users` WHERE ? LIKE CONCAT('%',?,'%') ORDER BY ? asc";
SET @searchCol = 'firstName';
set @searchQuery = 'o';
set @orderBy = 'lastName';
EXECUTE stm USING @searchCol, @searchQuery, @orderBy;
deallocate prepare stm;

Ожидаемое: Тревор, Блум, Трев Блум
Получено: ничего
* Я случайно наткнулся на этот случай. Я не уверен, почему один n будет работать, а один o не будет.


PREPARE stm FROM "SELECT firstName, lastName, displayName FROM `users` WHERE ? LIKE CONCAT('%',?,'%') ORDER BY ? asc";
SET @searchCol = 'firstName';
set @searchQuery = 'nn';
set @orderBy = 'lastName';
EXECUTE stm USING @searchCol, @searchQuery, @orderBy;
deallocate prepare stm;

Ожидаемое: Анна, Хоган, Анна Хоган
Получено: ничего


PREPARE stm FROM "SELECT firstName, lastName, displayName FROM `users` WHERE ? LIKE CONCAT('%',?,'%') ORDER BY ? asc";
SET @searchCol = 'firstName';
set @searchQuery = 'n';
set @orderBy = 'lastName';
EXECUTE stm USING @searchCol, @searchQuery, @orderBy;
deallocate prepare stm;

Ожидается: Несколько результатов, которые соответствуют %n%
Получено: Ожидаемые результаты


Я также попытался удалить CONCAT('%',?,'%'), заменив его на ? и изменив @searchQuery на %<query>%, но результаты те же, что и выше.

Из того, что я могу сказать, не генерируются сообщения об ошибках или ненормальные журналы.

Charset / Collation установлены на utf8 и utf_general_ci для таблицы users и соответствующих столбцов.

Ниже приведены результаты SHOW VARIABLES LIKE "%version%"

'innodb_version', '5.7.26'
'protocol_version', '10'
'slave_type_conversions', ''
'tls_version', 'TLSv1, TLSv1.1'
'version', '5.7.26-0ubuntu0.16.04.1-log'
'version_comment', '(Ubuntu)'
'version_compile_machine', 'x86_64'
'version_compile_os', 'Linux'

1 Ответ

1 голос
/ 03 июля 2019

Нельзя использовать ? заполнители для имен столбцов.Вместо значений используются заполнители, и они заменяются литеральным значением, которое вы указываете при выполнении оператора.

Когда вы пишете

PREPARE stm FROM "SELECT firstName, lastName, displayName FROM `users` WHERE ? LIKE CONCAT('%',?,'%') ORDER BY ? asc";
SET @searchCol = 'firstName';
set @searchQuery = 'o';
set @orderBy = 'lastName';
EXECUTE stm USING @searchCol, @searchQuery, @orderBy;

, запрос, который он выполняет, выглядит так:

SELECT firstName, lastName, displayName 
FROM `users` 
WHERE 'firstName' LIKE CONCAT('%','o','%') 
ORDER BY 'lastName' asc

Он не проверяет столбец firstName, он проверяет его как буквальную строку, что никогда не соответствует действительности, поскольку в firstName нет o.И это тоже не порядок по столбцу;это упорядочение по константе, что означает любой порядок.

Вам необходимо использовать обычную конкатенацию для замены имен столбцов, а не заполнителей.

SET @searchCol = 'firstName';
set @searchQuery = 'o';
set @orderBy = 'lastName';
PREPARE stm FROM CONCAT("
    SELECT firstName, lastName, displayName 
    FROM `users` 
    WHERE ", @searchCol, " LIKE CONCAT('%',?,'%') 
    ORDER BY ", @orderBy, " asc");
EXECUTE stm USING @searchQuery;
...