Я работаю над приложением 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 '#';
Мои вопросы:
LIKE
не работает должным образом?ESCAPE
?Вот рабочий пример, демонстрирующая проблему. Любая информация по этому поводу будет принята с благодарностью!
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 . Я создал скрипку, чтобы продемонстрировать проблему.
если вы ищете подстроку, используйтеlocate или instr. используйте Like только в том случае, если вам нужны подстановочные знаки. экранирование строк для Like — это больше проблем, чем пользы; в моем тестировании следующие символы нуждались в особой обработке [%_\\\0\n\r\x1a\xc2-\xf7]
но еще лучше не рассматривайте json как строку, используйте json_value(...) = ...
Один уровень обратной косой черты удаляется анализатором (если не указан sql_mode=NO_BACKSLASH_ESCAPES
) при сканировании строковых литералов из запроса.
Другой уровень обратной косой черты удаляется самим LIKE
(независимо от того, что такое sql_mode).
Итак, чтобы соответствовать, вам нужно поставить 4 раза \
за каждое настоящее лайком.
Благодарю за ваш ответ. Вы абсолютно правы. Согласно документации, обратные косые черты в предложении LIKE
служат двойной цели: они кодируют специальные символы, такие как символы новой строки и сами обратные косые черты, при анализе строки, а также экранируют подстановочные знаки. Это объясняет, почему использование символов, отличных от \, в предложении ESCAPE
приведет к совпадению (потому что, когда используются альтернативные escape-символы, обратные косые черты обрабатываются буквально и в соответствии с вашим правилом 4x они рационально совпадают).
(Без ESCAPE
) Количество необходимых вам обратных косых черт (\
) зависит от количества уровней программного обеспечения (приложение, соединитель и т. д.), через которые оно должно пройти. Каждый слой превратится \\
в \
. Когда SQL наконец получит это, вероятно, потребуется 1 обратная косая черта. Итак, попробуйте использовать 1, 2, 4, 8, чтобы увидеть, что работает.
(С ESCAPE '#'
), то это заменяет некоторые, но не все обратные косые черты. Поиграйте, пока не поймете все правильно. #\
или #\\
или я не знаю что.
Кроме того, имейте в виду, что «рабочий пример» — это один из этих «слоев». Поэтому все, что там работает, может не работать в вашем коде.