Версия сервера MySQL 10.3.9-MariaDB не может запрашивать текст с одинарной кавычкой

У меня есть база данных MySQL, в которой есть поле TagName со значением ~!@#$%^&*()_+|}{":?>‹./';[]\=-` Я пытаюсь выполнить запрос select TagName из taginfo, где TagName как '%@#$%';

Он показывает данные с тэгом, содержащим символ кавычки. Но я запрашиваю с оператором = и подобным оператором и добавляю больше кавычек '', чтобы принять одинарную кавычку, но он показывает пустой результат.

Я также пытаюсь добавить COLLATE UTF8_GENERAL_CI или изменить CHARACTER SET, но все безуспешно.

SELECT * from taginfo where tagname like '%~!@#$%^&*()_+|}{":?><./'';[]\=-`%';
SELECT * from taginfo where tagname like '%~!@#$%^&*()_+|}{":?><./'';[]\=-`%' COLLATE UTF8_GENERAL_CI;
SELECT * from taginfo where tagname COLLATE UTF8_GENERAL_CI like '%~!@#$%^&*()_+|}{":?><./'';[]\=-`%';

ALTER TABLE mytable CONVERT TO CHARACTER SET UTF8_GENERAL_CI
Error   2/19/2019 10:03:24 AM   0:00:00.039 <link> - MySQL Database Error: Unknown character set: 'UTF8_GENERAL_CI' 5   0

Версия сервера БД: MySQL 5.5.5 Информация о таблице MariaDB: введите здесь описание изображения

Вот результат запроса без одинарной кавычки: введите здесь описание изображения

Обновлено: я обнаружил проблему, заключающуюся в том, что если я запрашиваю без символа \, он показывает результат:

select TagName from taginfo where TagName like '%~!@#$%^&*()_+|}{":?><./'';[]%';

Но я добавил символ \ в конце он ничего не показывает:

select TagName from taginfo where TagName like '%~!@#$%^&*()_+|}{":?><./'';[]\%';

добавить больше всплеска все еще не работает

select TagName from taginfo where TagName like '%~!@#$%^&*()_+|}{":?><./'';[]\\%';

Обновлено: теперь проблема в том, что аналогичный запрос возвращает результат, но = запрос не возвращает ничего.

SELECT * from taginfo where tagname like '%~!@#$%^&*()_+|}{":?><./'';[]\\=-`%';
select * from taginfo where TagName =     '~!@#$%^&*()_+|}{":?><./'';[]\\=-`'

Обновлено: когда я пытаюсь создать БД в MySQL 8.0.13, этот запрос работает хорошо и возвращает 1 строку.

select * from taginfo1 where TagName = '~!@#$%^&*()_+|}{":?><./'';[]\\=-`';

Но в 10.3.9-MariaDB запрос

select * from taginfo1 where TagName = '~!@#$%^&*()_+|}{":?><./'';[]\\=-`';

не может вернуть никакого результата.

SELECT VERSION();

10.3.9-MariaDB


person Hien Nguyen    schedule 19.02.2019    source источник
comment
как насчет экранирования двух одинарных кавычек посередине перед ;   -  person danblack    schedule 19.02.2019
comment
поскольку в тексте есть только цитата, я добавляю цитату в mysql, принимаю ее   -  person Hien Nguyen    schedule 19.02.2019
comment
Пожалуйста, покажите нам фактические данные, которые вы пытаетесь сопоставить. Не совсем понятно, что вы пытаетесь здесь сделать.   -  person Tim Biegeleisen    schedule 19.02.2019
comment
@danblack Две литеральные одинарные кавычки - это экранированная одинарная кавычка, и они не должны приводить к прерыванию запроса.   -  person Tim Biegeleisen    schedule 19.02.2019
comment
Не дублируется, я проверял эту ссылку раньше   -  person Hien Nguyen    schedule 19.02.2019
comment
Ваш запрос SELECT * from taginfo where tagname like '%~!@#$%^&*()_+|}{":?><./'';[]\\=-`%'; неверен. Вы должны экранировать % и _, иначе эти символы будут «совпадать» с чем-то, чего вы, возможно, не ожидаете.   -  person fifonik    schedule 19.02.2019
comment
Я не думаю, что любое изменение COLLATION изменит результаты для этой строки. COLLATION в основном применяется для сравнения букв, особенно букв с ударением.   -  person Rick James    schedule 19.02.2019


Ответы (4)


Наконец я обнаружил проблему, потому что я установил этот режим.

SET @@SQL_MODE = CONCAT(@@SQL_MODE, ',NO_BACKSLASH_ESCAPES');

и этот запрос возвращает пустой

select * from taginfo where tagname = '~!@#$%^&*()_+|}{":?><./'';[]\\=-`'

Когда я удаляю NO_BACKSLASH_ESCAPES на SET @@SQL_MODE = 'NO_ENGINE_SUBSTITUTION';

select * from taginfo where tagname = '~!@#$%^&*()_+|}{":?><./'';[]\\=-`'

возвращает строку с тегом = ~!@#$%^&*()_+|}{":?>‹./';[]\=-`

person Hien Nguyen    schedule 12.03.2019

я пытаюсь установить

SET @@SQL_MODE = CONCAT(@@SQL_MODE, ',NO_BACKSLASH_ESCAPES');

И запрос на обновление добавить двойной \

SELECT * from taginfo where tagname like '%~!@#$%^&*()_+|}{":?><./'';[]\\=-`%';

Этот запрос возвращает правильный результат, но не работает с оператором =.

person Hien Nguyen    schedule 19.02.2019

Обратная косая черта — это экранирующий символ в MySQL. Вам нужно будет дважды экранировать его, например \\. Кроме того, при использовании условия LIKE знак процента и подчеркивание также необходимо экранировать (в противном случае вы можете сопоставить нерелевантные значения).

Вы можете увидеть, что происходит, просто выбрав значение, которое вы передаете:

SELECT '%~!@#$\%^&*()_+|}{":?><./'';[]\=-`%' test1;

| test1                            |
| -------------------------------- |
| %~!@#$%^&*()_+|}{":?><./';[]=-`% |

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

Теперь давайте дважды экранируем обратную косую черту, и она появится в выводе:

SELECT '%~!@#$\%^&*()\_+|}{":?><./'';[]\\=-`%' test2;

| test2                             |
| --------------------------------- |
| %~!@#$%^&*()_+|}{":?><./';[]\=-`% |

Просмотреть скрипт БД

person GMB    schedule 19.02.2019
comment
Я пробую ваш запрос select * from taginfo where tagname = '%~!@#$%^&*()_+|}{:?›‹./'';[]\\\=-`%', но это не работает - person Hien Nguyen; 19.02.2019
comment
Та же логика говорит, что подчеркивание (_) нужно экранировать. - person Rick James; 19.02.2019
comment
Можете ли вы помочь мне с равным оператором @GMB? - person Hien Nguyen; 19.02.2019

person    schedule
comment
Как уже было рекомендовано, вам необходимо предоставить свои данные, поскольку вы упомянули разные данные в разных запросах. Где-то откат в начале, где-то -- в конце. Это может быть проблемой, когда вы пытаетесь скопировать/вставить мой запрос выбора в свои данные. Вот почему я предоставил drop/create/insert + 2 x select. У меня работает на 5.5.8, 5.7 и mariadb 10.1.14 - person fifonik; 19.02.2019
comment
Вот значение тэга в моей базе данных ~!@#$%^&*()_+|}{:?›‹./';[]\=-` - person Hien Nguyen; 19.02.2019
comment
Обновил мой ответ вашими данными. - person fifonik; 19.02.2019
comment
Я попробовал запрос SELECT * FROM taginfo WHERE tagname = '~!@#$%^&*()_+|}{:?›‹./'';[]\\=-`'; но это не работает, вы можете мне помочь с равным оператором? - person Hien Nguyen; 19.02.2019
comment
Вы уверены, что у вас есть точная стоимость, которую вы указали? Это могут быть начальные или конечные пробелы, которые вызывают «проблему». Вы пытались скопировать/вставить мой код? Создайте тестовую базу данных на своем сервере и запустите код «как есть». Он возвращает результаты для всех двух вариантов выбора на моих серверах. - person fifonik; 19.02.2019