MariaDB LIKE с Escape-символом – неожиданное поведение

Я работаю над приложением Laravel с таблицей jobs, содержащей данные о заданиях в столбце payload. Полезная нагрузка представляет собой строку JSON, подобную этой:

{"displayName":"App\\Jobs\\V1\\ProcessOrdersPendingCourier"}

Я хочу получить записи, в которых ключ displayName в полезных данных JSON имеет значение "App\\Jobs\\V1\\ProcessOrdersPendingCourier". Логично, я использовал этот запрос:

SELECT * FROM `jobs`
WHERE `payload`
  LIKE '%"displayName":"App\\\\Jobs\\\\V1\\\\ProcessOrdersPendingCourier"%';

Однако этот запрос не возвращает результатов! После некоторых усилий я обнаружил, что добавление ESCAPE '#' к запросу волшебным образом извлекает ожидаемые строки:

SELECT * FROM `jobs`
WHERE `payload`
  LIKE '%"displayName":"App\\\\Jobs\\\\V1\\\\ProcessOrdersPendingCourier"%' ESCAPE '#';

Мои вопросы:

  1. Почему первый запрос LIKE не работает должным образом?
  2. Зачем в этом случае нужен символ ESCAPE?

Вот рабочий пример, демонстрирующая проблему. Любая информация по этому поводу будет принята с благодарностью!


Notes:

The # in escape '#' can be replaced with other characters like @ or & to act as the escape character. However, using \\ (backslash) as the escape character won't work in this scenario.

@danblack Спасибо, что поделились ссылкой на официальную документацию ESCAPE . Я создал скрипку, чтобы продемонстрировать проблему.

goodUser 22.05.2024 07:24

если вы ищете подстроку, используйтеlocate или instr. используйте Like только в том случае, если вам нужны подстановочные знаки. экранирование строк для Like — это больше проблем, чем пользы; в моем тестировании следующие символы нуждались в особой обработке [%_\\\0\n\r\x1a\xc2-\xf7] но еще лучше не рассматривайте json как строку, используйте json_value(...) = ...

ysth 22.05.2024 17:00
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Поиск нового уровня в Laravel с помощью MeiliSearch и Scout
Поиск нового уровня в Laravel с помощью MeiliSearch и Scout
Laravel Scout - это популярный пакет, который предоставляет простой и удобный способ добавить полнотекстовый поиск в ваше приложение Laravel. Он...
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
В последние годы архитектура микросервисов приобрела популярность как способ построения масштабируемых и гибких приложений. Laravel , популярный PHP...
Как построить CRUD-приложение в Laravel
Как построить CRUD-приложение в Laravel
Laravel - это популярный PHP-фреймворк, который позволяет быстро и легко создавать веб-приложения. Одной из наиболее распространенных задач в...
4
3
96
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

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

Один уровень обратной косой черты удаляется анализатором (если не указан sql_mode=NO_BACKSLASH_ESCAPES) при сканировании строковых литералов из запроса.

Другой уровень обратной косой черты удаляется самим LIKE (независимо от того, что такое sql_mode).

Итак, чтобы соответствовать, вам нужно поставить 4 раза \ за каждое настоящее лайком.

Благодарю за ваш ответ. Вы абсолютно правы. Согласно документации, обратные косые черты в предложении LIKE служат двойной цели: они кодируют специальные символы, такие как символы новой строки и сами обратные косые черты, при анализе строки, а также экранируют подстановочные знаки. Это объясняет, почему использование символов, отличных от \, в предложении ESCAPE приведет к совпадению (потому что, когда используются альтернативные escape-символы, обратные косые черты обрабатываются буквально и в соответствии с вашим правилом 4x они рационально совпадают).

goodUser 22.05.2024 14:43

(Без ESCAPE) Количество необходимых вам обратных косых черт (\) зависит от количества уровней программного обеспечения (приложение, соединитель и т. д.), через которые оно должно пройти. Каждый слой превратится \\ в \. Когда SQL наконец получит это, вероятно, потребуется 1 обратная косая черта. Итак, попробуйте использовать 1, 2, 4, 8, чтобы увидеть, что работает.

ESCAPE '#'), то это заменяет некоторые, но не все обратные косые черты. Поиграйте, пока не поймете все правильно. #\ или #\\ или я не знаю что.

Кроме того, имейте в виду, что «рабочий пример» — это один из этих «слоев». Поэтому все, что там работает, может не работать в вашем коде.

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