Почему MySQL возвращает строки, которые, по-видимому, не соответствуют предложению WHERE?
предположим, что пользовательский ввод
mysite.com/profile?identity=1
mysite.com/profile?identity=dinodsja
mysite.com/profile?identity=1a
получение значения
$identity = $_GET['identity']; // identity can be user_id or user_name
и у меня есть простой запрос select:
SELECT * FROM lb_users WHERE (user_id = 'dinodsja' OR user_name = 'dinodsja') AND user_status = 1
и он отлично работает. но проблема заключается в следующем:
SELECT * FROM lb_users WHERE (user_id = '1a' OR user_name = '1a') AND user_status = 1
когда я выполняю этот запрос, он также возвращает результат без выполнения условия.
Структура таблицы:
user_id bigint(25)
user_name varchar(50) utf8_general_ci
![enter image description here]()
**
-> Is this a MySQL Bug ?
-> How can we avoid this ?
-> What will be the query ?
**
Ответы
Ответ 1
Я давно помню, что у меня была аналогичная проблема.
Сначала немного фона: это не ошибка. Это на самом деле особенность. Хорошо, это может привести к такому неожиданному поведению, но MySQL, таким образом, очень толерантен w.r.t. пользовательские входы, соответствующие запросы выбора:
mysql> SELECT 'a' = 'a ';
-> 1
mysql> SELECT 'A' = 'a';
-> 1
Следовательно, при неявном преобразовании типов результат, например, '1a'
в INTEGER равен 1, но также:
mysql> SELECT 0 = 'x6';
-> 1
mysql> SELECT 1 = ' 1';
-> 1
mysql> SELECT 1 = ' 1a';
-> 1
Эта функция также реализована на других нестатически типизированных языках. PHP, например, вызывает этот тип жонглирования. См. Правила преобразования PHP String и этот пример из документации:
<?php
$foo = "0"; // $foo is string (ASCII 48)
$foo += 2; // $foo is now an integer (2)
$foo = $foo + 1.3; // $foo is now a float (3.3)
$foo = 5 + "10 Little Piggies"; // $foo is integer (15)
$foo = 5 + "10 Small Pigs"; // $foo is integer (15)
?>
Смотрите JavaScript:
<script>
document.write(parseInt("40 years") + "<br>");
</script>
=> 40
Тем не менее, решение вашей проблемы довольно просто: просто введите целое число в char и выполните сравнение:
mysql> SELECT * FROM lb_users WHERE (CAST(user_id AS CHAR) = '1' OR user_name = '1')
-> 1
mysql> SELECT * FROM lb_users WHERE (CAST(user_id AS CHAR) = '1a' OR user_name = '1a')
-> 0
mysql> SELECT * FROM lb_users WHERE (CAST(user_id AS CHAR) = 'dinodsja' OR user_name = 'dinodsja')
-> 1
Я сделал скрипку для всех, чтобы попробовать: http://sqlfiddle.com/#!2/c2835/14/0
Надеюсь, что это поможет,
-Hannes
Ответ 2
Причина этого в том, что тип данных столбца user_ID
является целым числом.
MySQL бесшумно помещает в значение значение NON-Number (и все, что следует за ним), поэтому 1a
равно 1
, так как a
будет удаляться в значение.
Ответ 3
Согласно вашему предыдущему сообщению
его пользовательский ввод для профиля. пользователь может указать user_id или user_name. поэтому вход действителен. но нет данных. - DBK 30 марта в 6:42
Я бы рекомендовал тестирование, чтобы увидеть, является ли его целое число и только поиск идентификатора пользователя, если он является целым числом. Это действительно более обходное решение для mySQL, не обрабатывающего сравнение STRING-INT, но оно должно работать.
declare @InputVar varchar(10)
set @InputVar = '1a'
SELECT *
FROM lb_users
WHERE
(case when isnumeric(@InputVar) = 1 then
case when (user_id = @InputVar OR user_name = @InputVar) then 1 else 0 end
else
case when user_name = @InputVar then 1 else 0 end
end =1 )
And
user_status = 1
Ответ 4
При работе со строками я бы использовал "LIKE" вместо "=", чтобы избежать безумства преобразования молчащего типа. LIKE используется для работы со строками, поэтому почему бы не использовать его.
Ответ 5
SELECT * FROM lb_users WHERE (user_id = '1a' OR user_name = '1a') AND user_status = 1
вы получите 1 результат, если вы измените '1a' на 1a, вы получите следующее:
# 1064 - У вас есть ошибка в синтаксисе SQL; проверьте руководство, соответствующее версии вашего сервера MySQL, для правильного синтаксиса для использования рядом с "1a LIMIT 0, 30" в строке 1
Это не ошибка, посмотрите http://dev.mysql.com/doc/refman/5.0/en/where-optimizations.html
надеюсь, что это поможет
Ответ 6
Я думаю, что вы не можете дублировать первичный ключ и идентификатор, я тестирую его, и я придумываю текущие данные... вы задали user_id своими атрибутами, например:
user_id bigint(50) auto_increment primary key
это не ошибка mysql.