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

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

3 ответа

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

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

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

DROP TABLE IF EXISTS `taginfo`;

CREATE TABLE `taginfo` (
    `tagname` VARCHAR(50) NULL DEFAULT NULL
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB
;

-- Notice single quote and backslash are escaped:
INSERT INTO `taginfo` (`tagname`) VALUES   ('~!@#$%^&*()_+|}{":?><./'';[]\\=-`'); 
SELECT * FROM `taginfo` WHERE tagname =     '~!@#$%^&*()_+|}{":?><./'';[]\\=-`'; 

-- Notice single quote, percent and underscore are escaped and backslash escaped twice
SELECT * FROM `taginfo` WHERE tagname LIKE  '~!@#$\%^&*()\_+|}{":?><./'';[]\\\\=-`';
SELECT * FROM `taginfo` WHERE tagname LIKE '%~!@#$\%^&*()\_+|}{":?><./'';[]\\\\=-`%';

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

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

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

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

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

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

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

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

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

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

Теперь давайте дважды избежим обратного слэша, и он появится в выводе:

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

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

Посмотреть на БД Fiddle

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