Почему сравнение строк в запросе MySQL не работает

Я запускаю очень простой запрос SELECT в MySQL, и он не работает.

SELECT string_name FROM table_name;

Это дает мне требуемый результат. Нравиться

  1. Это первая строка.
  2. Это строка два.
  3. Это строка три.

и так далее...

Но если я запускаю такой запрос

SELECT * FROM table_name WHERE string_name='This is string one'

Это не дает никакого результата. Я даже попробовал функцию TRIM.

SELECT * FROM table_name WHERE TRIM(string_name)=TRIM('This is string one')

Но это все еще не дает никакого результата.

Пожалуйста, предложите, что мне здесь не хватает. Это из-за какого-то форматирования или я делаю какую-то глупую ошибку. Кстати, строки сохраняются как VARCHAR в базе данных.

Наиболее распространенная причина, которую я видел для чего-то подобного, - это непечатаемые символы, скрытые в поле (под непечатаемостью я не имею в виду пробелы, о которых TRIM позаботился бы). Попробуйте использовать CHAR_LENGTH, чтобы увидеть, имеет ли какая-либо строка длину, которую вы не ожидаете. Кроме того, не уверен, что это просто вопрос презентации в вашем вопросе, но строки заканчиваются точками в вашем списке примеров, а не в проверке равенства вашего примера.

Uueerdo 28.05.2019 22:59

Вы пробовали использовать Нравиться?

tomerpacific 28.05.2019 23:01

Да, я пробовал CHAR_LENGTH, и это дает мне число на 1 или 2 больше, чем фактическая длина строки. Я думал, что это из-за пробелов, и поэтому я попробовал TRIM.

Rajan Benipuri 28.05.2019 23:03

Часто это управляющие символы, такие как разрывы строк, символы табуляции или разделители нулей, которые не отфильтровываются входным путем, из которого данные поступали в базу данных. В большинстве случаев обрезка не поможет. Обычно вы можете идентифицировать их, используя комбинацию строковых функций, чтобы получить коды ascii в каждой позиции, а затем исправить с помощью REPLACE, чтобы удалить проблемные символы. Это может быть немного болезненно, но обычно это первые или последние символы в строке и одни и те же символы для каждой проблемной строки, поэтому определение проблемных символов может происходить на раннем этапе процесса.

Uueerdo 28.05.2019 23:08

Кажется, это проблема. Я вставил данные из файла CSV, и я думаю, что разрыв строки вызывает проблему в моем запросе. Можете ли вы предложить, как мне проверить, есть ли в строках разрыв строки.

Rajan Benipuri 28.05.2019 23:13
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
0
5
2 627
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Пробовали ли вы использовать LIKE для целей отладки?
SELECT * FROM table_name WHERE string_name LIKE 'This is string one'

/!\ Не переключайтесь с = на LIKE, читайте почему здесь
TLDR:

  1. = is apparently 30x faster.
  2. Use = wherever you can and LIKE wherever you must.

Да, я пробовал LIKE, но результат не изменился.

Rajan Benipuri 28.05.2019 23:07

Я только что попробовал на своей машине, и она работает с =. Вы пробовали использовать двойной " вместо одинарного '? Если это все еще не работает, не могли бы вы поделиться структурой своей таблицы? Я пробовал с VARCHAR(255), и он работал без проблем.

marcoverbeek 28.05.2019 23:16

Извини, дружище, но я думаю, что мой вопрос тебе не ясен. Я знаю, что в обычных случаях = или LIKE оба оператора работают как положено. Пожалуйста, смотрите ответ @Uueerdo. В строках есть скрытые символы, и эти скрытые символы вызывают проблему.

Rajan Benipuri 28.05.2019 23:21

В самом деле, я только что прочитал его объяснение, и было бы понятно, что проблема возникает из-за разрывов строк в вашем CSV-файле. Пробовали ли вы импортировать CSV-файл после удаления этих разрывов строк? Или вы ищете способ, при котором разрывы строк не вызовут проблем в вашем SQL?

marcoverbeek 28.05.2019 23:23
= и LIKE — это две совершенно разные вещи, и странно, что кто-то предложил использовать LIKE вместо =. Ваш код должен быть готов к такому изменению, так как некоторые символы в LIKE (%, _) работают по-другому.
fifonik 28.05.2019 23:41

@fifonik, я предлагал использовать LIKE только для отладки и поиска источника проблемы. Под вторым пунктом в моей цитате я подразумевал, что в этой ситуации пользователь не должен использовать LIKE, а скорее =, потому что он могу или, по крайней мере, сможет, когда его проблема будет исправлена.

marcoverbeek 28.05.2019 23:45

Извините, я не увидел в вашем ответе, что предложение предназначено только для отладки. Кто-то в будущем может решить просто заменить '=' на 'LIKE'

fifonik 28.05.2019 23:54

@fifonik Вы правы. Я обновил свой ответ, чтобы отразить тот факт, что это было только предложение для целей отладки. Спасибо!

marcoverbeek 29.05.2019 00:05

Вы пробовали SELECT * FROM table_name WHERE string_name LIKE '%This is string one%'?

Leonardo 29.05.2019 00:15

Повторюсь из комментариев; иногда «непечатаемые» управляющие символы (например, символы новой строки) могут попасть в данные, для которых они никогда не предназначались. Вы можете проверить это, сравнив CHAR_LENGTH значений поля с тем, что вы видите на самом деле. Очевидно, что при больших объемах данных это может быть затруднительно; но если вы уже знаете одно проблемное значение, вы можете использовать этот метод, чтобы подтвердить, что это проблема в этой строке, прежде чем пытаться идентифицировать оскорбительный символ.

Как только эта проблема будет подтверждена, вы можете использовать запросы с функциями MySql ASC() и substring для идентификации кодов символов, пока не найдете символ; может быть лучше начать с конца строки и вернуться назад, так как часто оскорбительные символы находятся в конце.

Символ или символы, указанные в строках с известными проблемами, часто также являются причиной других строк с проблемами, поэтому определение проблемы в одной известной строке может фактически помочь решить все такие проблемы.

После того, как код(ы) символов идентифицирован(ы), такие запросы, как WHERE string_name LIKE CONCAT('%', CHAR(13), CHAR(10)), должны работать (в данном случае для традиционных строк новой строки Windows), чтобы идентифицировать другие похожие проблемные строки. Очевидно, настройте коды символов и подстановочные знаки в соответствии с вашими обстоятельствами.

Если ни в одной строке не должно быть этих символов, вы сможете очистить данные с помощью такого обновления: UPDATE theTable SET theString = REPLACE(REPLACE(theString, CHAR(10), ''), CHAR(13), '') удалить оскорбительные символы. Опять же, используйте коды, которые вы действительно наблюдали, вызывая проблему; и вы можете вместо этого преобразовать их в пробелы, если обстоятельства лучше обрабатываются таким образом, например, новая строка между двумя словами.

Ответ принят как подходящий

Прежде всего, я должен признать, что замечания, сделанные @Uueerdo, на самом деле были основной причиной этой проблемы. Даже я был в некоторой степени уверен, что в строке есть какие-то скрытые символы, вызывающие всю проблему, но я не знал, как найти и исправить этот оскорбительный символ.

Кроме того, подход, предложенный @Uueerdo для проверки и замены оскорбительного символа с использованием кода ASCII, кажется вполне законным, но, как он сам упомянул, этот процесс займет много времени, и нужно вручную проверять каждую строку на наличие этого оскорбительного символа, а затем замени это.

К счастью, потратив на это пару часов, я придумал гораздо более быстрый способ решения проблемы. Для этого, прежде всего, я хотел бы поделиться своим вариантом использования.

Мой первый запрос был для выбора всех строк из базы данных и печати результата на странице.

$result = mysqli_query($conn, "SELECT * from table_name");
while($row = mysqli_fetch_array($result)){
   $string_var = $row["string_name"]; 
   echo $string_var;
   echo "<br>";
}

Приведенный выше код работал, как и ожидалось, и печатал все string_name из таблицы. Теперь, если бы я хотел использовать переменную $string_var для другого запроса SELECT в той же таблице, это дало бы мне 0 результатов.

$result = mysqli_query($conn, "SELECT * FROM table_name");
while($row = mysqli_fetch_array($result)){
    $string_var = $row["string_name"];
    echo "String Name : ".$string_var."";
    $sec_result = ($conn, "SELECT * FROM table_name WHERE string_var='$string_name'");
    if (mysqli_num_rows($sec_result) > 0){
        echo "Has Results";
    } else {
        echo "No Results";
    }
}

В этом фрагменте мой второй запрос $sec_result всегда выдавал «Нет результатов».

Что я просто сделал, чтобы решить эту проблему.

$result = mysqli_query($conn, "SELECT * FROM table_name";
while ($row = mysqli_fetch_array($result)){
    $string_var = $row["string_name"];
    $row_id = $row["id"];

    $update_row = mysqli_query($conn, "UPDATE table_name SET string_name='$string_var' WHERE id=$row_id");
}

Этот шаг обновил все строки из таблицы без каких-либо скрытых/проблемных символов.

Я не обобщаю этот подход и не уверен, что он будет работать во всех случаях использования, но он помог мне решить мою проблему менее чем за минуту.

Я прошу @Uueerdo и других, кто лучше разбирается в этом, опубликовать более общий подход, чтобы он мог помочь другим, потому что я думаю, что многие люди, которые не могут найти правильный подход в таких условиях, в конечном итоге используют LIKE вместо =, но это полностью меняет основную идею запроса.

Другие вопросы по теме